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

JS中new Array与[]的行为差异:为何二维数组操作结果不同?

两段JS代码结果差异的原因

核心问题出在数组引用的复用上,拆解细节如下:

第一段代码的隐藏陷阱

第一段创建foo的过程里,关键漏洞在fill方法的使用:

const foo = new Array(2)
            .fill(new Array(2)) // 问题根源
            .map((subArr) => subArr.fill(0));
  • 调用fill(new Array(2))时,只会生成一个子数组实例,然后把这个子数组的引用填充到父数组的两个位置中。也就是说,foo[0]和foo[1]指向的是同一个数组对象,只是看起来是两个独立的子数组。
  • 后续的map遍历中,两次执行subArr.fill(0)都是在修改同一个数组,最终foo的两个元素依然共享同一个引用。

执行splice操作时:

const result = foo.map((subArr, index) => {
  subArr.splice(index, 1, 1);
  return subArr; 
});
  • 第一次遍历(index=0):修改共享子数组,将索引0的值改为1,数组变为[1, 0]。
  • 第二次遍历(index=1):还是修改这个共享子数组,将索引1的值改为1,数组变为[1, 1]。
  • 最终result里的两个元素都是被修改两次的共享数组,所以输出[[1, 1], [1, 1]]。

第二段代码的正常逻辑

第二段直接初始化foo:

const foo = [[0, 0], [0, 0]];

这里的两个[0, 0]是完全独立的数组实例,foo[0]和foo[1]指向不同的数组对象。

执行splice操作时:

  • 第一次遍历(index=0):修改foo[0],将索引0的值改为1,得到[1, 0]。
  • 第二次遍历(index=1):修改foo[1],将索引1的值改为1,得到[0, 1]。
  • 最终result里是两个各自被修改的独立数组,所以输出[[1, 0], [0, 1]]。

验证引用是否相同

可以用全等运算符验证子数组的引用关系:

  • 第一段代码执行console.log(foo[0] === foo[1]),输出true(两个子数组是同一引用)。
  • 第二段代码执行console.log(foo[0] === foo[1]),输出false(两个子数组是独立实例)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 07:04:51