繁体   English   中英

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

[英]Does “for…of” loop iteration follow the array order in JavaScript?

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

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

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

我对for...of 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); }

输出:

a
undefined
undefined
d

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

以上两点需要注意:

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

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

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); }

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

0
3
foo
bar

或者

foo
bar
0
3

或者是其他东西。 但是,从 ES2020 开始,它被指定为输出

0
3
foo
bar

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

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

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

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

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

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

根据 ES6 规范for..of

for ( LeftHandSideExpression of AssignmentExpression ) Statement

如果 LeftHandSideExpression 是 ObjectLiteral 或 ArrayLiteral,并且如果可以使用 AssignmentPattern 作为目标符号来解析与 LeftHandSideExpression 匹配的词法标记序列而没有剩余标记,则不应用以下规则。 相反,使用了 AssignmentPattern 的早期错误规则。

根据此语法规则定义,当 for..of 循环是数组对象字面量时,将按标记的词法顺序执行。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM