“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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 10:35:51  来源:igfitidea点击:

Does "for...of" loop iteration follow the array order in JavaScript?

javascriptfor-loopecmascript-6

提问by Heptic

Iterating over an array using for...indoesn't guarantee order, however ES6 introduces a new construct for...of.

迭代数组 usingfor...in并不能保证顺序,但是 ES6 引入了一个新的构造for...of

My limited testing of implementations of for...ofindicates 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...indoesn't guarantee order, however ES6 introduces a new construct for...of.

My limited testing of implementations of for...ofindicates that it does iterate in order on array, but is this property guaranteed?

迭代数组 usingfor...in并不能保证顺序,但是 ES6 引入了一个新的构造for...of

我对实现的有限测试for...of表明它确实在数组上按顺序迭代,但是这个属性是否有保证?

Yes, the order of for-ofon 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 undefineds show as blank in Babel's REPL.)

(这两个undefineds 在 Babel 的 REPL 中显示为空白。)

Two things to note above:

以上两点需要注意:

  1. Even though the array has an enumerable property foo, it isn't visited.

  2. The array is sparse, and for-ofdidvisit the two entries that aren't present (at indexes 1 and 2).

  1. 即使数组具有可枚举属性foo,它也不会被访问。

  2. 该数组是稀疏的,并且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, foobefore bar).

因为它必须首先按数字顺序访问整数索引属性(名称为标准数字形式的字符串的属性),然后按创建顺序访问其他属性(所以,foo之前bar)。

(That assumes there are no enumerable properties on Array.prototypeor Object.prototype(by default there aren't). If there were, we'd see them as well, but it's not specified where.)

(假设Array.prototypeor上没有可枚举的属性Object.prototype(默认情况下没有)。如果有,我们也会看到它们,但没有指定在哪里。)

If you want to loop through an array's values, for-ofis a great tool as of ES2015, alongside the other useful tools such as Array#forEach(forEachis particularly handy on sparse arrays; it skips the entries that don't exist). for-inis 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...ofindicate 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 ofdoesn't only iterate arrays (like for indoes 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 ArrayIteratorobjects, 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..ofloop works using iterators.

这是 David Walsh 的一个不错的博客链接http://davidwalsh.name/es6-generators,他在其中举例说明了for..of循环如何使用迭代器工作。