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

JavaScript Array.fill创建二维数组时push结果异常的原因

异常原因

问题核心是Array.fill()对引用类型的填充逻辑存在特性,你初始化二维数组的写法导致两个子数组实际是同一个对象:

  • Array.fill()的规则:如果传入的填充值是数组、对象这类引用类型,方法不会给数组每一项创建独立的新副本,而是把同一个内存引用复制到所有下标位置,所有下标最终指向同一个对象。
  • 两个数组的本质差异:
    • 数组a用字面量[[null,null],[null,null]]初始化,两个子数组是完全独立的实例,内存地址互不干扰,修改其中一个不会影响另一个。执行a[0] === a[1]会返回false。
    • 数组b用Array(2).fill(Array(2))初始化时,参数里的Array(2)仅执行1次,只生成1个长度为2的稀疏数组实例,外层数组的b[0]和b[1]存的是同一个引用,指向这唯一的子数组。执行b[0] === b[1]会返回true。
  • add(b)的实际执行逻辑:你预期map遍历会给两个独立子数组各追加1个null,但两次遍历操作的是同一个子数组:第一次遍历给这个子数组push一个null,长度从2变成3;第二次遍历又给同一个子数组push一个null,长度从3变成4。因为两个外层下标都指向这个长度为4的子数组,最终序列化结果就成了[[null,null,null,null],[null,null,null,null]]。

补充:最开始JSON.stringify()打印a、b结果一致,是因为序列化时只会读取对象的结构和可枚举值,既不会识别内部引用是否重复,还会自动把数组空槽转换为null,因此完全掩盖了两个数组的本质差异。

正确初始化独立子数组的写法

不要直接用fill()填充引用类型,改用回调逻辑每次生成新的子数组实例即可:

// 推荐写法1:Array.from 配合工厂回调
function na(){ 
  return Array.from({length: 2}, () => Array(2).fill(null)) 
}

// 推荐写法2:先填充基础类型再map生成子数组
function na(){
  return Array(2).fill(null).map(() => Array(2).fill(null))
}

内容的提问来源于stack exchange,提问作者João Otero

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 18:12:30