使用for...in迭代数组并不能保证顺序,但是ES6引入了一个新的结构for...of。我对for...of实现的有限测试表明,它确实在数组上按顺序迭代,但是这个属性能保证吗?
for...in
for...of
y53ybaqx1#
使用for...in迭代数组并不能保证顺序,但是ES6引入了一个新的结构for...of。我对for...of实现的有限测试表明,它确实在数组上按顺序迭代,但是这个属性能保证吗?是的,for-of在数组上的顺序由数组迭代器定义保证:它将以数字索引顺序访问数组中的条目(包括不存在的条目,例如稀疏数组中的条目-或者应该是稀疏数组中的那些 not:-)):下面是一个例子:
for-of
"use strict"; const a = []; a[3] = "d"; a[0] = "a"; a.foo = "f"; for (const v of a) { console.log(v); }
输出:
a undefined undefined d
上面要注意两点:1.即使数组具有可枚举属性foo,也不会访问它。1.数组是稀疏的,for-of确实访问了两个不存在的条目(索引1和2)。但是,for-in没有*没有 * 在ES 2015(又名“ES6”)到ES 2019中的保证顺序;在ES 2020中,它遵循与ES 2015中添加的顺序服从机制(Object.getOwnPropertyNames等)相同的属性顺序(有一些警告)。请考虑以下示例:
foo
for-in
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); }
在ES 2015到ES 2019中,它可能会输出
0 3 foo bar
或
foo bar 0 3
或者别的什么但是,从ES 2020及以后的版本开始,它被指定为输出
因为它必须首先以数字顺序访问 integer index 属性(名称为标准数字形式的字符串的属性),然后以 creation 顺序访问其他属性(因此,foo在bar之前)。(That假设Array.prototype或Object.prototype上没有可枚举属性(默认情况下没有)。如果有,我们也会看到它们,但没有指定在哪里。如果你想遍历数组的 * 值 *,for-of是ES 2015的一个很好的工具,还有其他有用的工具,如Array#forEach(forEach在稀疏数组上特别方便;它跳过不存在的条目)。for-in很少是一个好的选择。另一个答案中有一个详尽的选项列表。
bar
Array.prototype
Object.prototype
Array#forEach
forEach
wvmv3b1j2#
我对for...of实现的有限测试表明,它确实在数组上按顺序迭代,但是这个属性能保证吗?是的,但是查找它有点复杂,因为for of并不只是迭代数组(就像for in枚举对象一样)。相反,它一般地迭代所有 iterable 对象--按照它们各自的迭代器提供的顺序。事实上数组就是这样一个可迭代对象,当从数组中获取迭代器时,它将是一个迭代器,它以与数组中相同的顺序产生数组中的所有元素。你可以阅读ArrayIterator对象的规范,它们基本上像for (var index=0; index<array.length; index++) yield array[index];循环一样工作。
for of
for in
ArrayIterator
for (var index=0; index<array.length; index++) yield array[index];
7ivaypg93#
根据ES6规范,适用于..的
for ( LeftHandSideExpression of AssignmentExpression ) Statement
如果LeftHandSideExpression是ObjectLiteral或ArrayLiteral,并且如果可以使用AssignmentPattern作为目标符号来解析LeftHandSideExpression匹配的词汇标记序列而没有留下标记,则不应用以下规则。相反,使用AssignmentPattern的Early Error规则。根据这个语法规则定义,当它是Array或ObjectLiteral时,for..of循环将按照标记的词法顺序执行。这里是大卫沃尔什http://davidwalsh.name/es6-generators的一个很好的博客链接,他用例子解释了for..of循环如何使用迭代器。
for..of
3条答案
按热度按时间y53ybaqx1#
使用
for...in
迭代数组并不能保证顺序,但是ES6引入了一个新的结构for...of
。我对
for...of
实现的有限测试表明,它确实在数组上按顺序迭代,但是这个属性能保证吗?是的,
for-of
在数组上的顺序由数组迭代器定义保证:它将以数字索引顺序访问数组中的条目(包括不存在的条目,例如稀疏数组中的条目-或者应该是稀疏数组中的那些 not:-)):下面是一个例子:
输出:
上面要注意两点:
1.即使数组具有可枚举属性
foo
,也不会访问它。1.数组是稀疏的,
for-of
确实访问了两个不存在的条目(索引1和2)。但是,
for-in
没有*没有 * 在ES 2015(又名“ES6”)到ES 2019中的保证顺序;在ES 2020中,它遵循与ES 2015中添加的顺序服从机制(Object.getOwnPropertyNames
等)相同的属性顺序(有一些警告)。请考虑以下示例:在ES 2015到ES 2019中,它可能会输出
或
或者别的什么
但是,从ES 2020及以后的版本开始,它被指定为输出
因为它必须首先以数字顺序访问 integer index 属性(名称为标准数字形式的字符串的属性),然后以 creation 顺序访问其他属性(因此,
foo
在bar
之前)。(That假设
Array.prototype
或Object.prototype
上没有可枚举属性(默认情况下没有)。如果有,我们也会看到它们,但没有指定在哪里。如果你想遍历数组的 * 值 *,
for-of
是ES 2015的一个很好的工具,还有其他有用的工具,如Array#forEach
(forEach
在稀疏数组上特别方便;它跳过不存在的条目)。for-in
很少是一个好的选择。另一个答案中有一个详尽的选项列表。wvmv3b1j2#
我对
for...of
实现的有限测试表明,它确实在数组上按顺序迭代,但是这个属性能保证吗?是的,但是查找它有点复杂,因为
for of
并不只是迭代数组(就像for in
枚举对象一样)。相反,它一般地迭代所有 iterable 对象--按照它们各自的迭代器提供的顺序。事实上数组就是这样一个可迭代对象,当从数组中获取迭代器时,它将是一个迭代器,它以与数组中相同的顺序产生数组中的所有元素。你可以阅读
ArrayIterator
对象的规范,它们基本上像for (var index=0; index<array.length; index++) yield array[index];
循环一样工作。7ivaypg93#
根据ES6规范,适用于..的
如果LeftHandSideExpression是ObjectLiteral或ArrayLiteral,并且如果可以使用AssignmentPattern作为目标符号来解析LeftHandSideExpression匹配的词汇标记序列而没有留下标记,则不应用以下规则。相反,使用AssignmentPattern的Early Error规则。
根据这个语法规则定义,当它是Array或ObjectLiteral时,for..of循环将按照标记的词法顺序执行。
这里是大卫沃尔什http://davidwalsh.name/es6-generators的一个很好的博客链接,他用例子解释了
for..of
循环如何使用迭代器。