是否“for...of"循环迭代遵循 JavaScript 中的数组顺序? [英] Does "for...of" loop iteration follow the array order in JavaScript?

查看:21
本文介绍了是否“for...of"循环迭代遵循 JavaScript 中的数组顺序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

解决方案

使用 for...in 遍历数组并不能保证顺序,但是 ES6 引入了一个新的结构 for...of.

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

是的,数组迭代器定义:它将以数字索引顺序访问数组中的条目(包括不存在的条目,例如稀疏数组中的条目——或者也许那应该是稀疏数组中的那些 not :-) ):

现场示例 Babel 的 REPL,这里是使用最新浏览器的用户的现场代码段:

"use strict";让 a = [];[3] = 'd';a[0] = 'a';a.foo = "f";for (let v of a) {控制台日志(v);}

输出:

<前>一个不明确的不明确的d

(两个 undefined 在 Babel 的 REPL 中显示为空白.)

以上两点需要注意:

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

  2. 该数组是稀疏的,并且 for-of did 访问了两个不存在的条目(在索引 1 和 2 处).

for-in,但是,没有 没有在 ES2015 中没有保证顺序(又名";ES6") 到 ES2019;在 ES2020 中,它遵循与 ES2015 中添加的顺序服从机制相同的属性顺序(有一些注意事项)(Object.getOwnPropertyNames 等).考虑这个例子:

"use strict";var a = [];a.foo = "f";[3] = 'd';a[0] = 'a';a.bar = "b";变量键;for (key in a) {控制台日志(键);}

在 ES2015 到 ES2019 中,它可能会输出

<前>03富酒吧

<前>富酒吧03

或者别的什么.但是,从 ES2020 开始,它被指定为输出

<前>03富酒吧

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

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

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

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

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

解决方案

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

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

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 not in sparse arrays :-) ):

Live Example on Babel's REPL, and here's an on-site snippet for those using an up-to-date browser:

"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.)

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-of did visit the two entries that aren't present (at indexes 1 and 2).

for-in, however, does not did not 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:

"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

0
3
foo
bar

or

foo
bar
0
3

or something else. As of ES2020, though, it is specified to output

0
3
foo
bar

because it has to visit the integer index properties first (properties whose names are strings in standard numeric form) in numeric order, followed by other properties in creation order (so, foo before 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.)

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"循环迭代遵循 JavaScript 中的数组顺序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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