为什么forEach遍历数组时搭配pop操作无法遍历全部元素?
forEach遍历中途停止问题说明
这是Array.prototype.forEach的标准执行机制,并非运行异常:
- forEach启动时会按数组初始长度确定最大遍历索引,但每次执行回调前会校验当前遍历索引是否小于数组的实时长度,若索引大于等于当前数组长度,遍历会直接终止。
问题复现场景执行拆解
你提供的异常案例中,初始数组sentence长度为5,遍历过程如下:
- 第1次遍历:索引=0 < 初始长度5,执行回调后
pop删除数组最后一个元素,数组长度变为4,新数组推入This - 第2次遍历:索引=1 < 当前数组长度4,执行回调后
pop删除元素,数组长度变为3,新数组推入will - 第3次遍历:索引=2 < 当前数组长度3,执行回调后
pop删除元素,数组长度变为2,新数组推入all - 第4次遍历前校验:索引=3 >= 当前数组长度2,遍历直接终止,因此最终只返回3个元素。
第二段代码可以正常遍历的原因是运行过程中没有修改原数组长度,数组长度始终为5,索引0-4均满足小于数组长度的要求,因此可以遍历全部元素。
数组反转的正确实现方案
如果你需要实现数组反转,可参考以下几种方案:
方案1:倒序遍历原数组(不修改原数组)
const sentence = ['sense.','make', 'all', 'will', 'This']; function reverseArray(array) { let newArray = []; for (let i = array.length - 1; i >= 0; i--) { newArray.push(array[i]) } return newArray; } console.log(reverseArray(sentence)) // 输出:["This","will","all","make","sense."]
方案2:按初始数组长度执行pop(会修改原数组)
const sentence = ['sense.','make', 'all', 'will', 'This']; function reverseArray(array) { let newArray = []; // 先缓存初始长度,避免遍历提前终止 const originLength = array.length; for(let i = 0; i < originLength; i++) { newArray.push(array.pop()) } return newArray; } console.log(reverseArray(sentence))
方案3:使用内置reverse方法
如果不需要自定义逻辑,可直接使用数组自带的反转方法,若不想修改原数组可以先做浅拷贝:
const sentence = ['sense.','make', 'all', 'will', 'This']; // 不修改原数组的反转写法 const reversedArray = [...sentence].reverse(); console.log(reversedArray)
内容的提问来源于stack exchange,提问作者Marian07
相关产品推荐
相关产品推荐

