ES6是否为对象属性引入了明确定义的枚举顺序?

ES6是否为对象属性引入了明确定义的枚举顺序?

var o = { '1': 1, 'a': 2, 'b': 3 } Object.keys(o); // ["1", "a", "b"] - is this ordering guaranteed by ES6? for(let k in o) { console.log(k); } // 1 2 3 - is this ordering guaranteed by ES6? 

For for-inObject.keys不。

对于其他一些行动: 是的 ,通常。

虽然ES6 / ES2015添加了属性顺序,但由于传统兼容性问题,它不需要for-inObject.keys来遵循该顺序。

for-in循环根据[[Enumerate]]迭代,其中[定义为(强调我的)):

当调用O的[[Enumerate]]内部方法时,将采取以下步骤:

返回一个Iterator对象( 25.1.1.2 ),它的下一个方法迭代O的所有可枚举属性的String值。 Iterator对象必须从%IteratorPrototype%( 25.1.2 )继承。 枚举属性的机制和顺序 没有指定,但必须符合下面指定的规则[1]

ES7 / ES2016删除了[[Enumerate]]内部方法,而是使用抽象操作EnumerateObjectProperties ,但是就像[[Enumerate]]一样,它没有指定任何顺序。

还可以从Object.keys看到这个引用:

如果一个实现定义了for-in语句的特定枚举顺序,

这意味着实现不需要定义枚举的特定顺序 。 ECMAScript 2015语言规范的项目编辑Allen Wirfs-Brock在规范完成后的一篇文章中已经证实了这一点 。

其他操作,如Object.getOwnPropertyNamesObject.getOwnPropertySymbolsReflect.ownKeys ,按照以下顺序为普通对象:

  1. 整数索引(如果适用),按升序排列。
  2. 其他字符串键(如果适用),属性创建顺序。
  3. 符号键(如果适用),属性创建顺序。

此行为在[[OwnPropertyKeys]]内部方法中定义。 但是请注意, 异域对象可能会以不同方式定义该方法,例如

 console.log(Reflect.ownKeys(new Proxy({}, { ownKeys: () => ['3','1','2'] }))); // ['3','1','2'], the integer indices are not sorted!