这个问题出现好几次了,所以记个文档
但是我提醒在先
平常写代码不要依赖 for in 的遍历顺序
for in 遍历的顺序
简单测试
const data = { 'a': '000', '3': 'ccc', '1': 'aaa', 'b': 'bbb' }
const keys = [];
for(let i in data){
keys.push(i);
}
console.log(keys); // [ '1', '3', 'a', 'b' ]
当然,用 Object.keys
也是一样的
const data = { 'a': '000', '3': 'ccc', '1': 'aaa', 'b': 'bbb' }
const keys = Object.keys(data);
console.log(keys); // [ '1', '3', 'a', 'b' ]
规范
这个东西有规范吗?还真有。。。
ES2015 真的规范过,规范在这里
好吧,这个读起来有点累
这里有个更说人话的版本
Most Browsers iterate object properties as:
- Integer keys in ascending order (and strings like “1” that parse as ints)
- String keys, in insertion order (ES2015 guarantees this and all browsers comply)
- Symbol names, in insertion order (ES2015 guarantees this and all browsers comply)
简单总结一下就是:
- 数字 key 递增
- 字符串 key 随后,按插入序
- Symbol 最后,按插入序
尽管 ES2015 之前,没有明确规定,但是大部分引擎也都是这个顺序
这就是个典型的“事实标准”了,ES6 在这个地方把 backwards-compatibility 做的挺好的
Standards always follow implementations
这在web领域是常有的事情了
花里胡哨的有用吗?
别说,还真有那么点用,qiankun 以及 systemjs 就依赖了这个行为来获取对象最后一个新增的值。
当然我觉得这不太妙,也确实有人对 qiankun 的这种选择报以置疑(我也置疑过 233