Javascript ES6是否为对象属性引入了定义良好的枚举顺序?

Javascript ES6是否为对象属性引入了定义良好的枚举顺序?,javascript,ecmascript-6,Javascript,Ecmascript 6,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? 注意:从ES2020开始,即使是较旧的操作,如fo

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?

注意:从ES2020开始,即使是较旧的操作,如
for in
Object.key
也需要遵循属性顺序。这并没有改变一个事实,即对基本程序逻辑使用属性顺序可能不是一个好主意,因为非整数索引属性的顺序取决于属性的创建时间


ES2015-ES2019的答案:

对于
中的
对象.key
JSON.stringify
否。

对于某些其他操作:,通常

虽然ES6/ES2015添加了属性顺序,但由于遗留兼容性问题,它不需要遵循in
Object.keys
JSON.stringify
的属性顺序

循环根据进行迭代,定义为(emphasis mine):

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

返回下一个方法迭代的迭代器对象() 在O的可枚举属性的所有字符串值键上 迭代器对象必须继承自%IteratorPrototype%()。 枚举属性的机制和顺序不正确 指定的,但必须符合下面指定的规则[1]

ES7/ES2016删除[[Enumerate]]内部方法,而是使用抽象操作,但与[[Enumerate]]一样,它不指定任何顺序

另请参见以下引文:

如果实现为 在声明中,[…]

这意味着实现不需要定义特定的枚举顺序。这篇文章由ECMAScript 2015语言规范的项目编辑Allen Wirfs Brock在规范完成后发表的一篇文章中撰写

对于普通对象,其他操作(如、、和)遵循以下顺序:

  • 整数索引(如果适用),按升序排列
  • 其他字符串键(如果适用),按属性创建顺序
  • 符号键(如果适用),按属性创建顺序
  • 此行为在内部方法中定义。但某些人对内部方法的定义略有不同。例如,代理的
    ownKeys
    陷阱可以按任意顺序返回数组:

    console.log(Reflect.ownKeys)(新代理({}{
    ownKeys:()=>['3'、'1'、'2']
    
    }))); // ['3'、'1'、'2'],整数索引未排序注意:从ES2020开始,即使是较旧的操作,如in
    对象的
    。键也需要遵循属性顺序。这并没有改变一个事实,即对基本程序逻辑使用属性顺序可能不是一个好主意,因为非整数索引属性的顺序取决于属性的创建时间


    ES2015-ES2019的答案:

    对于
    中的
    对象.key
    JSON.stringify
    否。

    对于某些其他操作:,通常

    虽然ES6/ES2015添加了属性顺序,但由于遗留兼容性问题,它不需要遵循in
    Object.keys
    JSON.stringify
    的属性顺序

    循环根据进行迭代,定义为(emphasis mine):

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

    返回下一个方法迭代的迭代器对象() 在O的可枚举属性的所有字符串值键上 迭代器对象必须继承自%IteratorPrototype%()。 枚举属性的机制和顺序不正确 指定的,但必须符合下面指定的规则[1]

    ES7/ES2016删除[[Enumerate]]内部方法,而是使用抽象操作,但与[[Enumerate]]一样,它不指定任何顺序

    另请参见以下引文:

    如果实现为 在声明中,[…]

    这意味着实现不需要定义特定的枚举顺序。这篇文章由ECMAScript 2015语言规范的项目编辑Allen Wirfs Brock在规范完成后发表的一篇文章中撰写

    对于普通对象,其他操作(如、、和)遵循以下顺序:

  • 整数索引(如果适用),按升序排列
  • 其他字符串键(如果适用),按属性创建顺序
  • 符号键(如果适用),按属性创建顺序
  • 此行为在内部方法中定义。但某些人对内部方法的定义略有不同。例如,代理的
    ownKeys
    陷阱可以按任意顺序返回数组:

    console.log(Reflect.ownKeys)(新代理({}{
    ownKeys:()=>['3'、'1'、'2']
    
    }))); // ['3'、'1'、'2'],整数索引未排序
    正如另一个答案中所述,ES2015没有为in
    Object.keys
    JSON.stringify
    的(非常常用的)属性迭代方法
    定义枚举顺序,而为其他方法(如
    Reflect.ownKeys
    )定义枚举方法但是,这种不一致性很快将不再存在,所有属性迭代方法将以可预测的方式迭代。

    正如许多人在自己的JS体验和评论中可能观察到的那样,尽管上述方法的规范不能保证属性迭代顺序,但无论如何,每个实现几乎总是以相同的确定顺序进行迭代。因此,有一个(完成的)建议更改规范,以使此行为正式:

    (