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

JavaScript中两种二维矩阵创建方式的差异问题分析

为什么用Array.fill()创建二维数组会导致所有子数组同步变化?

核心原因和new关键字无关,问题出在引用类型的特性和Array.fill()的工作逻辑上:

1. dp1的异常根源

const dp1 = new Array(6).fill(new Array(4).fill(0));

这里new Array(4).fill(0)只会执行一次,生成唯一的一个数组实例。fill()方法的作用是把这个数组的内存引用,填充到外层数组的每一个索引位置。也就是说,dp1[0]、dp1[1]……dp1[5]指向的是同一个数组对象。

当你在循环中执行dp1[i][j] = ${i}, ${j}``时,本质上是在反复修改同一个底层数组:

  • 先修改dp1[5][j],此时所有子数组都会同步显示这个值
  • 接着修改dp1[4][j],覆盖之前的内容,所有子数组再次同步更新
  • 直到最后修改dp1[0][j],所有子数组最终都会显示这一轮的赋值结果,也就是你看到的全是['0, 0', '0, 1', '0, 2', '0, 3']。

你可以通过下面的代码验证引用相同:

console.log(dp1[0] === dp1[1]); // 输出 true,说明是同一个数组

2. dp2符合预期的原因

const dp2 = new Array(6);
for (let i = 0; i < 6; i++) {
    dp2[i] = new Array(4).fill(0);
}

循环的每一次迭代中,new Array(4).fill(0)都会生成一个全新的数组实例,每个实例都有独立的内存地址。dp2[0]到dp2[5]各自指向不同的数组,修改其中一个不会影响其他子数组,所以最终每个子数组的内容都是独立的。

验证引用独立的代码:

console.log(dp2[0] === dp2[1]); // 输出 false,说明是不同数组

3. 用fill()创建二维数组的正确写法

如果想一行代码创建独立的二维数组,可以结合map()方法,让每个外层数组元素都对应新的子数组:

const dp1 = new Array(6).map(() => new Array(4).fill(0));

map()会遍历外层数组的每个位置,每次回调都生成一个新的子数组,避免了引用共享的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 16:55:28