Ben*_*Ben 50 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?
Run Code Online (Sandbox Code Playgroud)
Ori*_*iol 68
对于for-in
和Object.keys
:不.
对于一些其他操作:是的,通常.
虽然ES6/ES2015添加了属性订单,但由于遗留兼容性问题,它不需要JSON.stringify
或for-in
遵循该订单.
Object.keys
循环根据[[Enumerate]]迭代,[定义为(强调我的):
当调用O的[[Enumerate]]内部方法时,采取以下步骤:
返回一个Iterator对象(25.1.1.2),其下一个方法迭代O的可枚举属性的所有String值键.Iterator对象必须从%IteratorPrototype%(25.1.2)继承.枚举属性的机制和顺序没有指定,但必须符合下面规定的规则[1].
ES7/ES2016删除[[Enumerate]]内部方法,而是使用抽象操作EnumerateObjectProperties,但就像[[Enumerate]]一样,它没有指定任何顺序.
并且还可以看到以下引用JSON.stringify
:
如果实现为for-in语句定义了特定的枚举顺序,[...]
这意味着不需要实现来定义特定的枚举顺序.ECMAScript 2015语言规范项目编辑Allen Wirfs-Brock在规范完成后发布的帖子中证实了这一点.
其他操作,如for-in
,Object.keys
和Object.getOwnPropertyNames
,不遵循普通对象的顺序如下:
此行为在[[OwnPropertyKeys]]内部方法中定义.但要注意外来物体可能会以不同方式定义该方法,例如
console.log(Reflect.ownKeys(new Proxy({}, {
ownKeys: () => ['3','1','2']
}))); // ['3','1','2'], the integer indices are not sorted!
Run Code Online (Sandbox Code Playgroud)
[1]下面说:
[[Enumerate]]必须获取目标对象的属性键, 就像调用其[[OwnPropertyKeys]]内部方法一样.
并且[[OwnPropertyKeys]]的顺序是明确定义的.但是不要让这让你感到困惑:"好像"只意味着"相同的属性",而不是"相同的顺序".
这可以在EnumerableOwnNames中看到,它使用[[OwnPropertyKeys]]来获取属性,然后命令它们
如果调用了[[Enumerate]]内部方法,将返回迭代器生成的相对顺序
如果[[Enumerate]]需要以与[[OwnPropertyKeys]]相同的顺序进行迭代,则不需要重新排序.
Cer*_*nce 11
作为覆盖对方的回答,ES2015不会为(很常用的)属性来定义枚举顺序迭代方法for-in
,Object.keys
和JSON.stringify
,而它也定义好其他方法,如枚举的方法Reflect.ownKeys
。但是,这种不一致很快就会不复存在,所有属性迭代方法都会以可预测的方式进行迭代。
正如许多人在他们自己的 JS 经验和评论中所观察到的那样,尽管上述这些方法的规范不保证属性迭代顺序,但无论如何,每个实现几乎总是以相同的确定性顺序进行迭代。因此,有一个(已完成的)提议来更改规范以使此行为正式化:
这个建议,在大多数情况下,for..in
,Object.keys
/ values
/ entries
,并JSON.stringify
保证迭代,以便在:
(1) 数字数组键
(2) 非符号键,按插入顺序
(3) 符号键,按插入顺序
这与Reflect.ownKeys
已经保证以这种方式迭代的其他方法的顺序相同。
的规范的文本是相当简单的:EnumerateObjectProperties
通过调用的问题抽象方法for..in
等,其顺序使用是未指定的,现在将调用[[OwnPropertyKeys]]
,这是它的迭代顺序内部方法被指定。
有一些奇怪的情况,目前的实现不同意,在这种情况下,结果顺序将继续是未指定的,但这种情况很少见。
这个问题是关于 EcmaScript 2015 (ES6)。但需要注意的是,EcmaScript2017 规范删除了之前出现在规范中的以下段落Object.keys
,这里引用自EcmaScript 2016 规范:
如果实现为 for-in 语句定义了特定的枚举顺序,则必须对步骤 3 中返回的数组元素使用相同的顺序。
此外,EcmaScript 2020 规范从 部分中删除了以下段落,该部分EnumerableOwnPropertyNames
仍然出现在 EcmaScript 2019 规范中:
- 对属性的元素进行排序,使它们的相对顺序与 Iterator 生成的相对顺序相同,如果使用O调用 EnumerateObjectProperties 内部方法,则返回该顺序。
这些清除意味着从EcmaScript的2020年起,Object.keys
实施统一的具体顺序Object.getOwnPropertyNames
和Reflect.ownKeys
,即在指定的OrdinaryOwnPropertyKeys。顺序是:
1个一种数组索引是一个字符串值属性密钥是一个规范的数字串2,其数值我的范围是从0的整数 我< 2 32 - 1。
2甲规范数字串是通过将产生一个数字的字符串表示ToString
,或字符串“-0”。例如,“012”不是规范数字字符串,但“12”是。
应该指出的是,所有主要的实现在几年前就已经与这个顺序保持一致。
归档时间: |
|
查看次数: |
13545 次 |
最近记录: |