ES6 是否为对象属性引入了明确定义的枚举顺序? [英] Does ES6 introduce a well-defined order of enumeration for object properties?

查看:19
本文介绍了ES6 是否为对象属性引入了明确定义的枚举顺序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Does ES6 introduce a well-defined order of enumeration for object properties?

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-inObject.键 需要遵循属性顺序.这并没有改变这样一个事实,即对基本程序逻辑使用属性顺序可能不是一个好主意,因为非整数索引属性的顺序取决于属性的创建时间.

Note: As of ES2020, even older operations like for-in and Object.keys are required to follow property order. That doesn't change the fact that using property order for fundamental program logic probably isn't a good idea, since the order for non-integer-index properties depends on when the properties were created.

ES2015-ES2019 的答案:

Answer for ES2015-ES2019:

对于 for-inObject.keysJSON.stringify:

对于其他一些操作:,通常.

For some other operations: Yes, usually.

虽然 ES6/ES2015 添加了属性顺序,但它不需要 for-inObject.keysJSON.stringify 遵循由于旧版兼容性问题,该顺序是这样的.

While ES6 / ES2015 adds property order, it does not require for-in, Object.keys, or JSON.stringify to follow that order, due to legacy compatibility concerns.

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

for-in loops iterate according to [[Enumerate]], which is defined as (emphasis mine):

O的[[Enumerate]]内部方法被调用如下采取的步骤:

When the [[Enumerate]] internal method of O is called the following steps are taken:

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

Return an Iterator object (25.1.1.2) whose next method iterates over all the String-valued keys of enumerable properties of O. The Iterator object must inherit from %IteratorPrototype% (25.1.2). The mechanics and order of enumerating the properties is not specified but must conform to the rules specified below [1].

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

ES7 / ES2016 removes the [[Enumerate]] internal method and instead uses the abstract operation EnumerateObjectProperties, but just like [[Enumerate]] it doesn't specify any order.

还可以从 Object 中看到这句话.键:

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

If an implementation defines a specific order of enumeration for the for-in statement, [...]

这意味着实现不需要定义特定的枚举顺序.此已被 ECMAScript 项目编辑 Allen Wirfs-Brock 确认2015 语言规范,在规范完成后发表的一篇文章中.

That means implementations are NOT required to define a specific order of enumeration. This has been confirmed by Allen Wirfs-Brock, Project Editor of the ECMAScript 2015 Language Specification, in a post made after the specification was complete.

其他操作,如Object.getOwnPropertyNames, Object.getOwnPropertySymbols, Object.definePropertiesReflect.ownKeys 对于普通对象,请遵循以下顺序:

Other operations, like Object.getOwnPropertyNames, Object.getOwnPropertySymbols, Object.defineProperties, and Reflect.ownKeys do follow the following order for ordinary objects:

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

此行为在 [[OwnPropertyKeys]] 内部方法.但是某些外来对象对内部方法的定义略有不同.例如,代理的 ownKeys 陷阱可能以任何顺序返回一个数组:

This behavior is defined in the [[OwnPropertyKeys]] internal method. But certain exotic objects define that internal method slightly differently. For example, a Proxy's ownKeys trap may return an array in any order:

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

[1] 下面写着:

[[Enumerate]] 必须获取目标对象自己的属性键好像通过调用它的 [[OwnPropertyKeys]] 内部方法.

[[Enumerate]] must obtain the own property keys of the target object as if by calling its [[OwnPropertyKeys]] internal method.

并且 [[OwnPropertyKeys]] 的顺序是明确定义的.但是不要让这让你感到困惑:那个好像"是对的.仅表示相同的属性",而不是相同的顺序".

And the order of [[OwnPropertyKeys]] is well-defined. But don't let that confuse you: that "as if" only means "the same properties", not "the same order".

这可以在 EnumerableOwnNames 中看到,它使用[[OwnPropertyKeys]] 获取属性,然后对它们进行排序

This can be seen in EnumerableOwnNames, which uses [[OwnPropertyKeys]] to get the properties, and then it orders them

与迭代器产生的相对顺序相同如果 [[Enumerate]] 内部方法被调用,将返回

in the same relative order as would be produced by the Iterator that would be returned if the [[Enumerate]] internal method was invoked

如果需要 [[Enumerate]] 以与 [[OwnPropertyKeys]] 相同的顺序进行迭代,则无需重新排序.

If [[Enumerate]] were required to iterate with the same order as [[OwnPropertyKeys]], there wouldn't be any need to reorder.

这篇关于ES6 是否为对象属性引入了明确定义的枚举顺序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆