正如标题所述,对于for-of
以外的索引,为什么undefined
用循环变量绑定到Array
来运行循环体迭代构造(forEach()
,for-in
等)
关于 不是 :
TypedArray
s Array
上“正确”迭代undefined
Array
个元素
以下非正式说明found on MDN不正确吗?
for...of
语句[...]调用一个自定义迭代钩子,该钩子将针对对象的每个不同属性的值执行语句。
即还会为不存在的属性调用它。
const sparse = [0, 1, 2] // Was [0, , 2], but some are unfamiliar with this syntax
// or think it creates the array [0, undefined, 2]
delete sparse[1]
for (let e of sparse) console.log('for-of', e)
// Contrast with:
sparse.forEach(e => console.log('forEach', e))
for (let i in sparse) console.log('for-in', sparse[i])
console.log('map', sparse.map(e => e)) // Note, prints incorrectly in the snippet
// console, check browser console
// etc.
这是预期的行为(Yes)吗,为什么要这样设计?
答案 0 :(得分:1)
for..of
调用Array迭代器方法,该方法在in the spec中进行了描述。
(2)让迭代器成为ObjectCreate(%ArrayIteratorPrototype%,« [[IteratedObject]],[[ArrayIteratorNextIndex]],[[ArrayIterationKind]]»)。
(4)将迭代器的[[ArrayIteratorNextIndex]]内部插槽设置为0。
然后,当迭代器被迭代时,在22.1.5.2.1 %ArrayIteratorPrototype%.next:中:
(6)令index为O的[[ArrayIteratorNextIndex]]内部插槽的值。
(10)如果index≥len,则
(10)(a)将O的[[IteratedObject]]内部插槽的值设置为undefined。
(10)(b)返回CreateIterResultObject(undefined,true)。
(11)将O的[[ArrayIteratorNextIndex]]内部插槽的值设置为index + 1 。
(创建值为
array[index]
的迭代器结果对象)
换句话说,迭代器从索引0开始进行迭代,并在每次调用.next()
时将索引增加1。它不检查该数组在该索引处是否真的有一个符号(稀疏数组不会),它只是检查该索引是否小于该数组的.length
另一方面,使用for..in
会迭代所有 enumerable 属性,并且数组本身的可枚举属性不包含稀疏数组索引。 / p>
const sparse = [0, , 2];
console.log(sparse.hasOwnProperty('0'));
console.log(sparse.hasOwnProperty('1'));
是的,这是预期的行为。