JavaScript中将数组push进另一数组结果不符合预期的原因求解
代码运行逻辑解析
你遇到的问题本质是JavaScript中引用类型的存储特性导致的,数组属于引用类型,变量存储的是数组在内存中的引用地址,而非数组本身的值。
你给出的原代码如下:
let newArray = []; let arr1 = []; for (let i = 0; i < 2; i++) { for (let j = 0; j < 2; j++) { arr1.push(0); } newArray.push(arr1); } console.log(newArray);
执行步骤拆解
- 初始化阶段:声明
newArray为空数组,arr1为空数组,此时arr1变量存储的是指向空数组的内存地址。 - 第一次外层循环(i=0):
内层循环执行2次,向arr1中推入2个0,arr1变为[0,0]
执行newArray.push(arr1)时,实际推入newArray的是arr1的内存地址,而非[0,0]的副本,此时newArray展示为[[0,0]] - 第二次外层循环(i=1):
内层循环再执行2次,继续向同一个arr1对应的内存空间推入2个0,arr1变为[0,0,0,0]
因为newArray中第一个元素指向的就是这个内存地址,所以此时newArray[0]会同步变为[0,0,0,0]
再次执行newArray.push(arr1),推入的还是同一个内存地址,最终newArray的两个元素都指向同一个数组,所以输出为[[0,0,0,0],[0,0,0,0]]
修复方案
场景1:实现你预期的[[0,0],[0,0,0,0]]效果(保留arr1每次迭代的长度快照)
推入newArray时对当前arr1做浅拷贝,存入数组的当前状态副本即可:
let newArray = []; let arr1 = []; for (let i = 0; i < 2; i++) { for (let j = 0; j < 2; j++) { arr1.push(0); } newArray.push([...arr1]); // 扩展运算符做浅拷贝,保存当前数组状态 } console.log(newArray); // 输出 [[0,0],[0,0,0,0]]
场景2:预期输出[[0,0],[0,0]](每次内层循环生成长度为2的独立数组)
把arr1的声明放到外层循环内部,每次循环创建独立的新数组即可:
let newArray = []; for (let i = 0; i < 2; i++) { let arr1 = []; // 每次循环创建新的独立数组 for (let j = 0; j < 2; j++) { arr1.push(0); } newArray.push(arr1); } console.log(newArray); // 输出 [[0,0],[0,0]]
内容的提问来源于stack exchange,提问作者g97
相关产品推荐
相关产品推荐

