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

JavaScript生成嵌套数组时所有元素被最后一项覆盖如何解决

二维数组转指定结构三维数组时元素被最后一项覆盖问题

问题复现

现有长度为3的二维数组c2,每个子数组长度为7,需要转换为[3][1][7]结构的三维数组,使用如下代码实现时,返回结果所有子项都被原数组最后一个子数组覆盖:

var c3 = new Array(players).fill(new Array(1).fill(new Array(7)))
// 原始c2结构
// c2= [
//     [x1, x2, x3, x4, x5, x6, x7],
//     [y1, y2, y3, y4, y5, y6, y7],
//     [z1, z2, z3, z4, z5, z6, z7]
// ]

c2.forEach(function (val, ind) {
    c3[ind][0] = c2[ind]
})

// 预期输出
// [
//     [[x1, x2, x3, x4, x5, x6, x7]],
//     [[y1, y2, y3, y4, y5, y6, y7]],
//     [[z1, z2, z3, z4, z5, z6, z7]]
// ]

// 实际输出
// [
//     [[z1, z2, z3, z4, z5, z6, z7]],
//     [[z1, z2, z3, z4, z5, z6, z7]],
//     [[z1, z2, z3, z4, z5, z6, z7]]
// ]

根本原因

Array.fill()传入引用类型值(数组、对象等)时,不会为每个填充位置创建独立副本,所有位置都会指向同一个内存地址的同一个实例。
上述初始化代码中,new Array(1).fill(new Array(7))仅执行了1次,也就是说c3的3个一级元素,本质是同一个长度为1的数组的三个引用。后续遍历赋值时,每次修改c3[ind][0]都是在修改这同一个数组的第0位,最后一次赋值(z数组)会覆盖之前的所有修改,最终所有位置读取到的都是最后一次赋值的结果。

修复方法

初始化多层数组时,要保证每一层的引用类型都是独立创建的,不要直接用fill嵌套填充引用值,有两种简单的实现方式:

方式1:初始化时就创建独立数组实例

用Array.from的映射函数为每个一级元素生成独立数组:

// 初始化时每个一级元素都是新建的独立数组,不存在引用共用
const c3 = Array.from({ length: players }, () => [new Array(7)])

c2.forEach((val, ind) => {
    c3[ind][0] = val
})

方式2:遍历时新建包裹数组

如果不需要提前初始化固定长度的空数组,可以直接在遍历过程中构造每一项的结构:

const c3 = []
c2.forEach(val => {
    c3.push([val]) // 每一项都新建一个数组包裹当前遍历到的子数组
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 08:31:06