关于 js forEach 的疑问?

以下代码在 chrome 输出 1,2,3

const arr = [1,2,3]
arr.forEach(i=>{
    arr.push(i)
    console.log(i)
})

这个在网上找到了,forEach 一开始就已经获取了 数组长度

The range of elements processed by forEach is set before the first call to callbackfn. Elements which are appended to the array after the call to forEach begins will not be visited by callbackfn.

但是怎么解释以下代码 只输出了 1?

const arr = [1,2,3]
arr.forEach(i=>{
    if(i===1) arr.length = 0
    console.log(i)
})

网上都查过了, 找不到
期望有大佬 能贴出源码

阅读 802
4 个回答

这一点,和 empty 有关。

你的后一段代码,在执行到 arr.length = 0 后,会导致数组的元素全部清空,而 forEach() 在执行回调参数前,会判断一下对应位置的元素是否为 empty,当值为 empty 时,会直接不执行。

比如:

const arr = [, null, undefined];
console.log(arr.length);
arr.forEach((i) => {
  console.log(i);
});
// 依次输出:3、null、undefined
// 诶,数组长度不是为 3 吗,第一个怎么没有任何输出?
// 因为 arr[0] 为 empty

更多分析,你可以看看我的一篇记录,研究过这一点是怎么回事。

参见:https://blog.csdn.net/qq_49661519/article/details/126809280

赞同一楼。
不过这个现象还可以从另外一个角度解释——数组的迭代方法会跳过数组空槽
比如下面的例子:

[,,,3,4] === 5; // true
[,,,3,4].forEach(console.log);

👆 [,,,3,4].length 其实是 5 ,但console.log只会被调用两次。

数组迭代方法跳过空槽的行为,还会引发一些反直觉的现象,比如:

[,,,,,].every((item) => typeof item === "number");
// true
推荐问题
logo
Microsoft
子站问答
访问
宣传栏