是否“;对于的“;循环迭代遵循JavaScript中的数组顺序

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

本文关键字:JavaScript 顺序 数组 循环 是否 迭代      更新时间:2023-09-26

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

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

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

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

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

这里有一个例子:

"use strict";
const a = [];
a[3] = "d";
a[0] = "a";
a.foo = "f";
for (const v of a) {
    console.log(v);
}

输出:

一未定义的未定义的d

上面需要注意的两件事:

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

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

然而,for-in在ES2015(又名"ES6")至ES2019中没有保证订单;在ES2020中,它遵循与ES2015中添加的服从顺序机制(Object.getOwnPropertyNames等)相同的属性顺序(有一些注意事项)

"use strict";
const a = [];
a.foo = "f";
a[3] = "d";
a[0] = "a";
a.bar = "b";
for (const key in a) {
    console.log(key);
}

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

03.foo酒吧

foo酒吧03.

或者其他什么。

然而,从ES2020及以后,它被指定为输出

03.foo酒吧

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

(假设Array.prototypeObject.prototype上没有可枚举属性(默认情况下没有)。如果有,我们也会看到它们,但没有具体说明在哪里。)

如果您想循环遍历数组的for-of是ES2015的一个很好的工具,与Array#forEach等其他有用的工具一样(forEach在稀疏数组上特别方便;它跳过不存在的条目)。CCD_ 19很少是一个好的选择。在另一个答案中有一个详尽的选项列表。

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

是的。但是查找它有点复杂,因为for of不仅仅迭代数组(就像for in枚举对象一样)。相反,它一般迭代所有可迭代的对象——按照它们各自的迭代器提供的顺序。

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

根据…的ES6规范。。

for ( LeftHandSideExpression of AssignmentExpression ) Statement

如果LeftHandSideExpression是ObjectLiteral或ArrayLiteral,如果词法标记序列与LeftHandSideExpression可以使用AssignmentPattern作为目标符号,则以下规则不适用应用相反,AssignmentPattern的早期错误规则是习惯于

根据这个语法规则的定义。。当循环是ArrayObjectLiteral时,循环将按标记的词法顺序执行。

这是大卫·沃尔什的一个不错的博客链接http://davidwalsh.name/es6-generators他举例说明了CCD_ 25循环是如何使用迭代器工作的。