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

为何用Array.prototype.fill()创建矩阵时,修改单个元素致所有行值同步变化?

为什么修改矩阵的一个元素会导致所有行对应位置都改变?

这是一个非常典型的JavaScript引用类型复用问题,我来给你拆解清楚:

问题根源:Array.fill()复用了同一个数组引用

你的代码里,arr.fill(row())这一行是关键问题:

  • row()只会被调用一次,返回一个单独的子数组对象
  • fill()方法会把这个子数组的引用,填充到arr的每一个索引位置上

也就是说,你创建的矩阵里,所有的行其实都是同一个数组对象。在JavaScript中,数组属于引用类型——当你把一个数组赋值给多个变量/数组元素时,它们保存的不是数组的副本,而是指向内存中同一个数组的指针。所以当你修改arr[2][2]时,本质上是在修改那个唯一的子数组,自然所有行的对应位置都会跟着变化。

修复方案:为每一行生成独立的数组

我们需要确保每一行都是一个全新的数组,而不是复用同一个引用。可以用Array.map()来替代fill(),因为map()会为每个元素执行一次回调函数,每次都会生成新的子数组:

function Matrix(x,y,value){
  if(value === undefined){
    value = null;
  }
  // 用map生成每一行,每次回调都创建新的子数组
  return new Array(y).map(() => {
    let subarr = new Array(x);
    subarr.fill(value);
    return subarr;
  });
}

测试一下修复后的代码:

let arr = Matrix(5,5);
arr[2][2] = 'marked as duplicate';
console.log(arr);

这时候就只有第三行(索引2)的第三列元素会被修改,其他行保持不变。

额外提醒:如果value是引用类型怎么办?

如果你的value是对象、数组这类引用类型,即使修复了行的问题,每一行里的所有元素还是会指向同一个引用。这时候你需要在填充子数组时,为每个元素创建新的引用,比如用循环赋值而不是fill(),或者使用Array.from()来生成子数组:

// 当value是引用类型时的示例修复
function Matrix(x,y,value){
  if(value === undefined){
    value = null;
  }
  // 假设value是对象,需要每次创建新对象
  return new Array(y).map(() => {
    return Array.from({length: x}, () => {
      // 如果是对象,这里要返回新的对象副本,比如 {...value}
      return typeof value === 'object' ? {...value} : value;
    });
  });
}

内容的提问来源于stack exchange,提问作者Filip Fry Toman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:17:35