"for ... of"循环迭代是否遵循JavaScript中的数组顺序?

Hep*_*tic 28 javascript for-loop ecmascript-6

使用数组迭代for...in不保证顺序,但ES6引入了新的构造for...of.

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

T.J*_*der 26

使用数组迭代for...in不保证顺序,但ES6引入了新的构造for...of.

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

是的,数组迭代器定义for-of保证了数组的顺序:它将以数字索引顺序访问数组中的条目(包括那些不存在的条目,例如稀疏数组中的条目 - 或者可能是那些不是在稀疏数组中:-)):

关于 Babel的REPL的实例,这里是使用最新浏览器的现场片段:

"use strict";
let a = [];
a[3] = 'd';
a[0] = 'a';
a.foo = "f";
for (let v of a) {
  console.log(v);
}
Run Code Online (Sandbox Code Playgroud)

输出:

a
undefined
undefined
d

(这两个undefined在巴贝尔的REPL中显示为空白.)

上面有两点需要注意:

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

  2. 阵列是稀疏的,并且for-of 没有访问两个条目中不存在(在索引1和2).

for-in然而,即使在ES2015(又名"ES6")中也没有保证订单.这是很容易读取规格,使得它,但它不支持; 请参阅此答案了解详情.另请注意,for-in在数组上使用不仅会访问数组的"索引",还会访问所有数组的可枚举属性名称,包括非索引属性名称.例如,即使在ES2015中,这个:

"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);
}
Run Code Online (Sandbox Code Playgroud)

......可能输出:

0
3
foo
bar

...要么

foo
bar
0
3

...或其他东西,虽然很可能使用当前的JavaScript实现集(但规范不要求),所有数字键("索引")将在其他属性之前或之后组合在一起.

假设没有可枚举的属性Array.prototypeObject.prototype(默认情况下没有).如果有,我们也会看到它们.

如果你想循环遍历数组的,那么它for-of是ES2015的一个很好的工具,以及其他有用的工具,例如Array#forEach(forEach在稀疏数组上特别方便;它会跳过不存在的条目).for-in很少是一个很好的选择.在另一个答案中有一个详尽的选项列表.


Ber*_*rgi 5

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

是.但是追捕它有点复杂,因为for of它不仅迭代数组(就像for in枚举对象一样).相反,它通常迭代所有可迭代对象 - 按其各自迭代器提供的顺序.

实际上,数组是可迭代的,当从它们获取迭代器时,它将是一个迭代器,它以与在数组中找到的顺序相同的顺序产生数组的所有元素.您可以阅读对象规范ArrayIterator,它们基本上像for (var index=0; index<array.length; index++) yield array[index];循环一样工作.