为什么 for-of 不跳过稀疏数组的空槽? [JavaScript]

Why does for-of not skip empty slots of a sparse Array? [JavaScript]

正如标题所说,为什么 for-of 运行 循环 body 与 循环变量 绑定到 undefined对于不在 Array 中的索引,而其他迭代构造(forEach()for-in 等)不?

澄清: 因为很多人误解了问题

不是关于:


以下非正式描述found on MDN不正确吗?

The for...of statement [...] invokes a custom iteration hook with statements to be executed for the value of each distinct property of the object.

即它还为 non-existent 属性调用。

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.

这是预期的行为吗 () 以及为什么要这样设计?

for..of调用数组迭代器方法,描述为in the spec.

(2) Let iterator be ObjectCreate(%ArrayIteratorPrototype%, «‍[[IteratedObject]], [[ArrayIteratorNextIndex]], [[ArrayIterationKind]]»).

(4) Set iterator’s [[ArrayIteratorNextIndex]] internal slot to 0.

然后,当遍历迭代器时,在22.1.5.2.1 %ArrayIteratorPrototype%.next::

(6) Let index be the value of the [[ArrayIteratorNextIndex]] internal slot of O.

(10) If index ≥ len, then

(10) (a) Set the value of the [[IteratedObject]] internal slot of O to undefined.

(10) (b) Return CreateIterResultObject(undefined, true).

(11) Set the value of the [[ArrayIteratorNextIndex]] internal slot of O to index+1.

(create iterator result object whose value is array[index])

换句话说 - 迭代器从索引 0 开始迭代,并在每次调用 .next() 时将索引递增 1。它不会检查数组是否确实 在该索引处有 项(稀疏数组不会)——它只是检查索引是否小于 .length数组的。

for..in相反,所有可枚举属性都被迭代,数组自身的可枚举属性不包括 稀疏数组索引。

const sparse = [0, , 2];
console.log(sparse.hasOwnProperty('0'));
console.log(sparse.hasOwnProperty('1'));

所以是的,这是有意为之的行为。