You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS中for...of循环操作数组:为何两次执行结果不符预期?

for...of循环中push+shift操作导致数组结果不符预期的原因

现象对比

仅push扩展数组的情况

let arr = [1, 2, 3];
for (e of arr) {
  arr.push(arr[arr.length - 1] + 1);
  if (arr.length >= 10) break;
}
console.log(arr) // 输出: [1,2,3,4,5,6,7,8,9,10]

这段代码里,for...of遍历数组时,每次push新元素都会让数组长度实时增加,迭代器会持续遍历新加入的元素,直到数组长度达到10触发break,最终得到完整的1-10数组。

push+shift操作数组的情况

let arr = [1, 2, 3];
for (e of arr) {
  arr.push(arr[arr.length - 1] + 1);
  if (arr[arr.length - 1] >= 10) break;
  arr.shift();
}
console.log(arr) // 输出: [4,5,6]

这里原本预期输出[8,9,10],但实际结果却是[4,5,6],核心原因在于for...of依赖的数组迭代器的遍历逻辑。

核心原因解析

for...of循环本质是调用数组的Symbol.iterator生成迭代器,数组的默认迭代器遵循索引递增遍历的逻辑:

  • 迭代器从索引0开始,每次调用next()就访问当前数组的arr[i],然后索引i自增1
  • 当i >= 当前数组的长度时,迭代器返回done: true,循环直接终止

结合案例2的执行流程看:

  1. 初始数组[1,2,3],迭代器索引i=0,取出元素1,push后数组变为[1,2,3,4],因4<10执行shift,数组变为[2,3,4],索引i自增到1
  2. 当前数组[2,3,4],索引i=1取出元素3,push后变为[2,3,4,5],5<10执行shift,数组变为[3,4,5],索引i自增到2
  3. 当前数组[3,4,5],索引i=2取出元素5,push后变为[3,4,5,6],6<10执行shift,数组变为[4,5,6],索引i自增到3
  4. 此时数组长度是3,i=3 >= 3,迭代器直接终止循环,根本没机会触发arr[arr.length-1]>=10的break条件,最终数组停留在[4,5,6]

而案例1中,数组长度随push持续增加,迭代器的索引i可以一直递增,直到数组长度达到10触发break,因此能得到预期结果。

内容的提问来源于stack exchange,提问作者RainClick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 15:51:42