JavaScript二维数组fill方法赋值异常的原因咨询
二维数组赋值异常的原因解析
问题背景
想要创建一个按整数顺序填充的3×3二维数组,写出如下代码后实际输出不符合预期,同时疑惑new Array(3)为何不会引发引用错误:
代码示例
let length = 3 let arrMatrix = (new Array(3)).fill(Array(3)); arrMatrix.fill((new Array(3)).fill(0)); var sum = 0; for(let i=0; i<length; i++) { for(let j=0; j<length; j++) { arrMatrix[i][j] = sum; sum += 1; } } console.log(arrMatrix);
实际输出
[ [ 6, 7, 8 ], [ 6, 7, 8 ], [ 6, 7, 8 ] ]
期望输出
[ [ 0, 1, 2 ], [ 3, 4, 5 ], [ 6, 7, 8 ] ]
问题原因
1. fill方法的引用类型共享问题
Array.prototype.fill()填充引用类型(比如数组)时,只会把该对象的内存地址复制到数组的每个位置,而非创建新的独立对象。
你的代码中,第二次调用arrMatrix.fill((new Array(3)).fill(0))时,(new Array(3)).fill(0)仅创建了一个数组对象,fill把这个数组的引用赋值给了arrMatrix的三个元素——也就是说,arrMatrix[0]、arrMatrix[1]、arrMatrix[2]指向的是同一个数组。
循环赋值时,你每次修改的都是这个共享数组的对应位置,最后一轮循环(i=2)将数组修改为[6,7,8],所以最终三个位置显示的都是这个结果。
2. new Array(3)为何不报错
new Array(3)是合法的JavaScript语法,它会创建一个长度为3的稀疏数组(数组本身是有效的对象,只是内部未初始化元素),因此可以正常调用fill方法,不会触发引用错误。
正确实现方式
要让二维数组的每个子数组都是独立对象,可使用map方法生成:
let length = 3; // 先填充undefined,再通过map生成独立子数组 let arrMatrix = new Array(length).fill().map(() => new Array(length).fill(0)); var sum = 0; for(let i=0; i<length; i++) { for(let j=0; j<length; j++) { arrMatrix[i][j] = sum; sum += 1; } } console.log(arrMatrix);
或更简洁的写法,直接在生成阶段填充序列:
let length = 3; let arrMatrix = Array.from({ length }, (_, i) => Array.from({ length }, (_, j) => i * length + j) ); console.log(arrMatrix);
内容的提问来源于stack exchange,提问作者DrEarnest
相关产品推荐
相关产品推荐

