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

JavaScript中fill与循环创建矩阵行为差异原因探究

为什么用Array.fill创建矩阵和循环创建的行为差这么多?

哈哈,这个问题我当初刚学JS的时候也踩过一模一样的坑!先看你遇到的情况:

// 用.fill创建矩阵
var aMatrix = new Array(5).fill(new Array(5));
aMatrix[0][0] = 'X';
// 结果所有行的第0个元素都变成了'X'
console.log(aMatrix);

为啥会出现这种“牵一发而动全身”的情况?核心问题出在Array.fill对引用类型的处理上,咱们一步步掰扯清楚:

罪魁祸首:引用类型的复用

JavaScript里的数据类型分两种:原始类型(比如数字、字符串、null)和引用类型(比如数组、对象)。当你把引用类型传给Array.fill()的时候,它不会给数组的每个位置都创建一个新的实例——而是把同一个引用复制到了每一个位置。

换句话说,你创建的aMatrix里的5个“行”,其实全都是指向同一个数组对象的指针!所以你修改aMatrix[0][0]的时候,本质上是在修改那个唯一的底层数组,自然所有行都会跟着同步变化。

循环创建为啥就没问题?

如果换成循环的方式:

var aMatrix = [];
for (let i = 0; i < 5; i++) {
  aMatrix.push(new Array(5)); // 每次循环都new一个新数组
}
aMatrix[0][0] = 'X';
console.log(aMatrix); // 只有第一行的第0个元素是'X'

这里每次循环都会调用new Array(5),生成一个全新的数组实例,然后把这个新数组的引用加到aMatrix里。每一行都是独立的个体,修改其中一行完全不会影响其他行。

想用fill又不想踩坑?这样写就行

如果还是喜欢fill的简洁写法,可以结合map来规避引用复用的问题:

var aMatrix = new Array(5).fill(null).map(() => new Array(5));
aMatrix[0][0] = 'X';
console.log(aMatrix); // 正常只有第一行变

先拿fill(null)填充(null是原始类型,不存在引用共享的问题),然后用map遍历每个位置,返回一个新的数组实例。这样每一行都是独立的,完美解决问题。

最后再划个重点

  • 用Array.fill填充引用类型时,数组所有位置共享同一个引用,修改一处全变;
  • 循环创建矩阵时,每次生成新的实例,各行相互独立;
  • 想兼顾fill的简洁和正确性,就用fill + map的组合。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:40:30