js对象乱序现象

背景

当我们使用 for...in 遍历一个Object对象时,打印的结构是否按key的顺序打印出来呢?
答案是:不一定

如case1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var obj = {
'-1': '全部',
'0' : '正常',
'1' : '失效'
};
for (let key in obj) {
console.log(key, obj[key]);
}

/*
'0' 正常
'1' 失效
'-1' 全部
*/

解惑

Object的key的排序规则到底是什么样的呢?答案是:
如果key是 0正整数字符串0字符串正整数,则安排从小到大排序,如果有其他的数据,安排创建顺序排列。
如case2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var obj = {
'a': 1,
'你' : 2,
'1' : 3,
'2.1' : 3
};
for (let key in obj) {
console.log(key, obj[key]);
}

/*
1 3
a 1
你 2
2.1 3
*/

解决办法

对于case1,如何让key顺序输出呢?可以先将key换成非整数类型的字符串,输出的时候再还原。
改造case1:

1
2
3
4
5
6
7
8
9
10
11
12
13
var obj = {
'-1.': '全部',
'0.' : '正常',
'1.' : '失效'
}
for (let key in obj) {
console.log(~~key, obj[key]);
}
/*
'-1' 全部
'0' 正常
'1' 失效
*/

但如果是case2各种数据类型混合的情况,就不能使用~~了

1
2
3
4
5
6
7
8
9
var obj = {
'.a': 1,
'.你' : 2,
'.1' : 3,
'.2.1' : 3
};
for (let key in obj) {
console.log(key.substring(1), obj[key]);
}