“for...of”循环迭代是否遵循 JavaScript 中的数组顺序?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29477973/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Does "for...of" loop iteration follow the array order in JavaScript?
提问by Heptic
Iterating over an array using for...in
doesn't guarantee order, however ES6 introduces a new construct for...of
.
迭代数组 usingfor...in
并不能保证顺序,但是 ES6 引入了一个新的构造for...of
。
My limited testing of implementations of for...of
indicates that it does iterate in order on array, but is this property guaranteed?
我对实现的有限测试for...of
表明它确实在数组上按顺序迭代,但是这个属性是否有保证?
采纳答案by T.J. Crowder
Iterating over an array using
for...in
doesn't guarantee order, however ES6 introduces a new constructfor...of
.My limited testing of implementations of
for...of
indicates that it does iterate in order on array, but is this property guaranteed?
迭代数组 using
for...in
并不能保证顺序,但是 ES6 引入了一个新的构造for...of
。我对实现的有限测试
for...of
表明它确实在数组上按顺序迭代,但是这个属性是否有保证?
Yes, the order of for-of
on arrays is guaranteed by the array iterator definition: It will visit the entries in the array in numeric index order (including ones that don't exist, such as those in sparse arrays — or perhaps that should be those notin sparse arrays :-) ):
是的,for-of
数组的顺序由数组迭代器定义保证:它将以数字索引顺序访问数组中的条目(包括不存在的条目,例如稀疏数组中的条目 - 或者应该是那些不存在的条目)在稀疏数组中 :-) ):
Live Exampleon Babel's REPL, and here's an on-site snippet for those using an up-to-date browser:
Babel的 REPL上的实时示例,这是使用最新浏览器的用户的现场代码片段:
"use strict";
let a = [];
a[3] = 'd';
a[0] = 'a';
a.foo = "f";
for (let v of a) {
console.log(v);
}
Output:
输出:
a undefined undefined d
(The two undefined
s show as blank in Babel's REPL.)
(这两个undefined
s 在 Babel 的 REPL 中显示为空白。)
Two things to note above:
以上两点需要注意:
Even though the array has an enumerable property
foo
, it isn't visited.The array is sparse, and
for-of
didvisit the two entries that aren't present (at indexes 1 and 2).
即使数组具有可枚举属性
foo
,它也不会被访问。该数组是稀疏的,并且
for-of
确实访问了不存在的两个条目(在索引 1 和 2 处)。
for-in
, however, does notdidnot have a guaranteed order in ES2015 (aka "ES6") through ES2019; in ES2020, it follows the same property order (with some caveats) as the order-obeying mechanisms added in ES2015 (Object.getOwnPropertyNames
, etc.). Consider this example:
for-in
但是,也不能根本没有在ES2015(又名“ES6”)通过ES2019保证秩序; 在 ES2020 中,它遵循与 ES2015 中添加的顺序服从机制相同的属性顺序(有一些注意事项)(Object.getOwnPropertyNames
等)。考虑这个例子:
"use strict";
var a = [];
a.foo = "f";
a[3] = 'd';
a[0] = 'a';
a.bar = "b";
var key;
for (key in a) {
console.log(key);
}
In ES2015 through ES2019, it might output
在 ES2015 到 ES2019 中,它可能会输出
0 3 foo bar
or
或者
foo bar 0 3
or something else. As of ES2020, though, it is specified to output
或者是其他东西。但是,从 ES2020 开始,它被指定为输出
0 3 foo bar
because it has to visit the integer indexproperties first (properties whose names are strings in standard numeric form) in numeric order, followed by other properties in creationorder (so, foo
before bar
).
因为它必须首先按数字顺序访问整数索引属性(名称为标准数字形式的字符串的属性),然后按创建顺序访问其他属性(所以,foo
之前bar
)。
(That assumes there are no enumerable properties on Array.prototype
or Object.prototype
(by default there aren't). If there were, we'd see them as well, but it's not specified where.)
(假设Array.prototype
or上没有可枚举的属性Object.prototype
(默认情况下没有)。如果有,我们也会看到它们,但没有指定在哪里。)
If you want to loop through an array's values, for-of
is a great tool as of ES2015, alongside the other useful tools such as Array#forEach
(forEach
is particularly handy on sparse arrays; it skips the entries that don't exist). for-in
is rarely a good choice. There's an exhaustive list of options in this other answer.
如果你想遍历数组的值,这for-of
是 ES2015 的一个很好的工具,还有其他有用的工具,例如Array#forEach
(forEach
在稀疏数组上特别方便;它跳过不存在的条目)。for-in
很少是一个好的选择。在这个其他答案中有一个详尽的选项列表。
回答by Bergi
My limited testing of implementations of
for...of
indicate it does iterate in order on array, but is this property guaranteed?
我对 的实现的有限测试
for...of
表明它确实在数组上按顺序迭代,但是这个属性是否有保证?
Yes. But hunting it down is a littlebit complicated, as for of
doesn't only iterate arrays (like for in
does enumerate objects). Instead, it generically iterates all iterableobjects - in the order that their respective iterator supplies.
是的。但是寻找它有点复杂,因为for of
它不仅迭代数组(就像for in
枚举对象一样)。相反,它通常迭代所有可迭代对象——按照它们各自的迭代器提供的顺序。
In fact arrays are such an iterable, and when getting an iterator from them it will be an iterator that yields all elements of the array in the same order as they can be found in the array. You can read the spec for ArrayIterator
objects, they basically work like a for (var index=0; index<array.length; index++) yield array[index];
loop.
事实上,数组是一种可迭代的,当从它们获取迭代器时,它将是一个迭代器,它以在数组中找到的相同顺序生成数组的所有元素。您可以阅读objects的规范ArrayIterator
,它们基本上像for (var index=0; index<array.length; index++) yield array[index];
循环一样工作。
回答by Diptendu
As per ES6 spec for for..of
根据 ES6 规范for..of
for ( LeftHandSideExpression of AssignmentExpression ) Statement
If LeftHandSideExpression is either an ObjectLiteral or an ArrayLiteral and if the lexical token sequence matched by LeftHandSideExpression can be parsed with no tokens left over using AssignmentPattern as the goal symbol then the following rules are not applied. Instead, the Early Error rules for AssignmentPattern are used.
如果 LeftHandSideExpression 是 ObjectLiteral 或 ArrayLiteral,并且如果可以使用 AssignmentPattern 作为目标符号解析与 LeftHandSideExpression 匹配的词法标记序列而没有剩余标记,则不应用以下规则。相反,使用了 AssignmentPattern 的早期错误规则。
As per this grammar rule definition a for..of loop will be executed in the lexical order of the tokens when it is an Arrayor ObjectLiteral.
根据此语法规则定义,当 for..of 循环是数组或对象字面量时,将按标记的词法顺序执行。
Here is a nice blog link by David Walsh http://davidwalsh.name/es6-generatorswhere he has explained with example how a for..of
loop works using iterators.
这是 David Walsh 的一个不错的博客链接http://davidwalsh.name/es6-generators,他在其中举例说明了for..of
循环如何使用迭代器工作。