这个问题出现好几次了,所以记个文档

但是我提醒在先
平常写代码不要依赖 for in 的遍历顺序

for in 遍历的顺序

简单测试

  1. const data = { 'a': '000', '3': 'ccc', '1': 'aaa', 'b': 'bbb' }
  2. const keys = [];
  3. for(let i in data){
  4. keys.push(i);
  5. }
  6. console.log(keys); // [ '1', '3', 'a', 'b' ]

当然,用 Object.keys 也是一样的

  1. const data = { 'a': '000', '3': 'ccc', '1': 'aaa', 'b': 'bbb' }
  2. const keys = Object.keys(data);
  3. console.log(keys); // [ '1', '3', 'a', 'b' ]

规范

这个东西有规范吗?还真有。。。
ES2015 真的规范过,规范在这里

image.png

好吧,这个读起来有点累

这里有个更说人话的版本

Most Browsers iterate object properties as:

  1. Integer keys in ascending order (and strings like “1” that parse as ints)
  2. String keys, in insertion order (ES2015 guarantees this and all browsers comply)
  3. Symbol names, in insertion order (ES2015 guarantees this and all browsers comply)

简单总结一下就是:

  1. 数字 key 递增
  2. 字符串 key 随后,按插入序
  3. Symbol 最后,按插入序

尽管 ES2015 之前,没有明确规定,但是大部分引擎也都是这个顺序
这就是个典型的“事实标准”了,ES6 在这个地方把 backwards-compatibility 做的挺好的

Standards always follow implementations

这在web领域是常有的事情了

花里胡哨的有用吗?

别说,还真有那么点用,qiankun 以及 systemjs 就依赖了这个行为来获取对象最后一个新增的值

当然我觉得这不太妙,也确实有人对 qiankun 的这种选择报以置疑(我也置疑过 233