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

FCC练习题:JavaScript二维数组循环行为异常原因排查

问题原因分析

你遇到的问题本质是JavaScript中引用类型的赋值特性导致的:

  • 数组属于引用类型,你在函数最外层声明的let row = [],全程只有这一个数组对象存在。你每次调用newArray.push(row)时,推入的并不是row数组的独立副本,而是指向同一个row对象的内存地址引用。
  • 后续你对同一个row数组做的所有修改,都会同步反映到所有指向这个地址的引用上,也就是你debug时看到的newArray里已有元素同步更新的现象。

循环过程拆解

我们可以一步步还原3次外层循环的实际执行逻辑:

  1. 第一次外层i=0循环:内层循环给row推入2个0,row变为[0,0],将row的引用推入newArray,此时newArray为[<指向row的引用>]
  2. 第二次外层i=1循环:内层循环给同一个row再推入2个0,row变为[0,0,0,0],newArray里的第一个元素因为指向同一个内存地址,同步更新为[0,0,0,0],之后再把同一个引用推入newArray,现在newArray里两个元素都指向同一个row
  3. 第三次外层i=2循环:内层循环再给row推入2个0,row变为[0,0,0,0,0,0],newArray里前两个元素同步更新,再推入同一个引用,最终三个元素全部指向同一个长度为6的数组,就出现了你看到的输出结果。
解决方案

方案1:生成标准m行n列的全0矩阵

如果你的预期是得到3行2列的全0矩阵[[0,0],[0,0],[0,0]],只需要把row数组的声明放到外层for循环内部,每次循环都创建全新的独立数组即可:

function zeroArray(m, n) {  
  let newArray = [];
  for (let i = 0; i < m; i++) {
    // 每次外层循环都创建全新的row数组,避免引用共享
    let row = [];
    for (let j = 0; j < n; j++) {      
      row.push(0);
    }    
    newArray.push(row);
  }
  return newArray;
}

方案2:生成你描述的递增长度预期输出

如果你的预期就是你提到的每行长度依次递增n个0的结果[[0,0],[0,0,0,0],[0,0,0,0,0,0]],不需要改row的声明位置,只需要在推入newArray时传递row的浅拷贝即可:

function zeroArray(m, n) {  
  let newArray = [];
  let row = [];
  for (let i = 0; i < m; i++) {    
    for (let j = 0; j < n; j++) {      
      row.push(0);
    }    
    // 推入row的浅拷贝,后续修改原row不会影响已推入的元素
    newArray.push([...row]);
  }
  return newArray;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 10:15:03