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

为什么for不跳过稀疏数组的空插槽?[JavaScript],javascript,iteration,sparse-matrix,for-of-loop,Javascript,Iteration,Sparse Matrix,For Of Loop,正如标题所说,为什么for of运行循环体,循环变量绑定到undefined,索引不在数组中,而其他迭代构造(forEach(),for in,等等)不运行循环体 澄清:许多人误解了这个问题 它不是关于: 迭代TypedArrays(不能稀疏)或任何其他类 如何在稀疏的数组上“正确”迭代(其他方法似乎都是按预期方式工作的) 跳过数组中未定义的元素 以下非正式描述是否不正确 语句[…]的for…调用一个自定义迭代钩子,其中包含要为对象的每个不同属性的值执行的语句 也就是说,对于不存在的属性也

正如标题所说,为什么
for of
运行循环体,循环变量绑定到
undefined
,索引不在
数组中,而其他迭代构造(
forEach()
for in
,等等)不运行循环体

澄清:许多人误解了这个问题 它不是关于:

  • 迭代
    TypedArray
    s(不能稀疏)或任何其他类
  • 如何在稀疏的
    数组上“正确”迭代(其他方法似乎都是按预期方式工作的)
  • 跳过
    数组中未定义的
    元素

以下非正式描述是否不正确

语句[…]的
for…调用一个自定义迭代钩子,其中包含要为对象的每个不同属性的值执行的语句

也就是说,对于不存在的属性也会调用它

constsparse=[0,1,2]//Was[0,2],但有些人不熟悉这种语法
//或者认为它创建了数组[0,未定义,2]
删除稀疏[1]
for(让e表示稀疏)console.log('for-of',e)
//与之相比:
sparse.forEach(e=>console.log('forEach',e))
for(让我输入稀疏)console.log('for-in',sparse[i])
console.log('map',sparse.map(e=>e))//注意,在代码段中打印不正确
//控制台,检查浏览器控制台

//等。
for..of
调用数组迭代器方法,如下所述

(2) 让迭代器为ObjectCreate(%ArrayIteratorPrototype%,«‍[[IteratedObject]]、[[ArrayIteratorEndex]]、[[ArrayIterationKind]»)

(4) 将迭代器的[[ArrayItemOrnDex]]内部插槽设置为0

然后,当迭代器被迭代时,在:

(6) 设索引为O的[[ArrayItemOrneDex]]内部插槽的值

(10) 如果索引≥ 莱恩,那么

(10) (a)将O的[[IteratedObject]]内部插槽的值设置为未定义

(10) (b)返回CreateIterResultObject(未定义,true)

(11) 将O的[[ArrayIteratorNedex]]内部插槽的值设置为索引+1

(创建迭代器结果对象,其值为
数组[索引]

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

另一方面,对于
中的..,所有可枚举属性都被迭代,并且数组自身的可枚举属性不包括稀疏数组标记

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

console.log(sparse.hasOwnProperty('1'))谢谢你的回答。Re:>它不检查数组在该索引中是否有项,我很难解释规范,有
14。让elementValue成为Get(a,elementKey)
15。ReturnIfAbrupt(elementValue)
Get
调用
[[Get]]
,它具有
2。设desc为O.[GetOwnProperty]](P)
3。ReturnIfAbrupt(desc)
。。因此,对于不在数组中的索引,这不会导致突然完成(
continue
?或
throw
?)算法不会抛出,并返回
Array。[[Get]](elementKey,Array)
,它在任何地方都找不到键,最终到达
c。如果parent为null,则返回undefined。
。访问对象中不存在的属性只会返回
undefined
-它不会抛出(另一方面,尝试访问
undefined
null
的属性将抛出)-因此这里没有突然完成。不,抱歉,它会抛出