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

JS数组字面量与Array.fill()创建数组的赋值行为差异原因

核心原因

两种写法创建的二维数组,内层数组的引用关系完全不同:

  • 字面量写法let arrLiteral = [[0,0,0],[0,0,0],[0,0,0]]创建时,外层数组包含的3个内层数组是完全独立的3份实例,各自占用独立内存,修改其中某一个内层数组的元素,不会对另外两个内层数组产生任何影响,这也是符合常规预期的行为。
  • Array(3).fill(Array(3).fill(0))的写法踩了fill方法的特性坑:fill接收的参数如果是对象/数组这种引用类型,它不会自动复制多份实例,只会把同一个内存引用填充到数组的每一个位置。也就是说这行代码执行时,只创建了1个[0,0,0]的内层数组,外层数组的3个下标arrFill[0]、arrFill[1]、arrFill[2]全指向这同一个数组。你修改任何一个下标对应的内层数组元素,本质都是在改这唯一的一个数组,三个位置的输出当然会完全同步。
对应代码的实际执行过程

循环里给arrFill赋值的过程,本质是反复覆盖同一个数组的值:

  1. 第一层循环i=0(对应字符串"abc"):给这个共享数组的0、1、2位依次赋值'a'、'b'、'c',此时打印arrFill的三个元素,全是['a','b','c']
  2. 第一层循环i=1(对应字符串"def"):又给同一个共享数组的0、1、2位依次覆盖成'd'、'e'、'f',此时三个元素全变成['d','e','f']
  3. 第一层循环i=2(对应字符串"g"):字符串长度只有1,只把共享数组的0位覆盖成'g',剩下1、2位保留之前的'e'、'f',最终这个共享数组的值就是['g','e','f'],三个下标指向同一个数组,就出现了你看到的异常输出。
正确的多维数组创建方式

如果想用非字面量的方式生成内层独立的二维数组,不要直接给fill传引用类型值,可以搭配映射回调,让每个位置都生成新的独立数组:

// 方式1:用Array.from的映射回调,每次循环生成新数组
let arr1 = Array.from({ length: 3 }, () => Array(3).fill(0))

// 方式2:先用基础值fill占位,再map返回新的内层数组
let arr2 = Array(3).fill(null).map(() => Array(3).fill(0))

这两种写法生成的二维数组,每个内层数组都是独立实例,赋值表现和字面量创建的数组完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 09:33:19