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

JavaScript array.push追加数组时替换所有元素而非新增的问题

问题原因

你的验证结论完全正确,问题出在循环内对row变量的操作逻辑上:整个函数执行过程中你只创建了一个row数组实例,全程都在修改这同一个数组的内容,从来没有给row变量重新赋过新数组。
逐行梳理genArray的执行流程就能定位问题:

  • 函数启动时,在循环外声明let row = [],内存中只生成了一个空数组,row变量持有这个数组的引用
  • 第一次外层i循环:内层j循环往这个唯一的row里依次push 0、1,此时row内容为[0,1],你把这个数组的引用存入mainArr
  • 第二次外层i循环:既没有重置row,也没有给row赋新数组,还是往原来的那个数组里继续push 0、1,此时row内容变成[0,1,0,1],再次把同一个数组的引用存入mainArr
  • 第三次外层i循环:继续往同一个数组里push 0、1,row内容变为[0,1,0,1,0,1],第三次存入mainArr的还是同一个数组的引用

最终mainArr里的3个元素,本质是3个指向同一块内存地址的引用,所以打印出来三个元素完全一致,都是row最后一次被修改后的内容。
你自己写的验证代码里,arr2 = [2,4]属于给变量重新赋值,会让arr2指向新的数组实例,和之前存入arr1的旧数组没有关联,自然不会影响arr1的内容;但你循环里的操作,完全对应obj1.name = "Mike"这种直接修改引用指向对象本身内容的场景,所有指向这个对象的引用都会同步体现修改,和你验证的结论完全一致。

修复方案

两种常用写法都可以实现预期效果:

  • 方案1:把row的声明移到外层循环内部,每次外层循环启动时都创建一个全新的独立数组,保证每次存入mainArr的都是不同的数组实例
function genArray(m, n) {
  let mainArr = [];
  for (let i = 0; i < m; i++) {
    let row = []; // 每次循环新建独立数组
    for (let j = 0; j < n; j++) {
        row.push(j);
    }
    mainArr.push(row)
  }
  return mainArr;
}
  • 方案2:保留row在循环外的声明,push的时候传入row的浅拷贝,切断和原数组的引用关联,后续修改原row不会影响已经存入mainArr的内容
function genArray(m, n) {
  let mainArr = [];
  let row = [];
  for (let i = 0; i < m; i++) {
    for (let j = 0; j < n; j++) {
        row.push(j);
    }
    mainArr.push([...row]) // 传入当前row的浅拷贝
    // 也可以用mainArr.push(row.slice())实现同样效果
  }
  return mainArr;
}

两种写法执行后,调用genArray(3,2)都会得到预期输出:

[ [ 0, 1 ], [ 0, 1, 0, 1 ], [ 0, 1, 0, 1, 0, 1 ] ]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 05:54:14