JavaScript修改嵌套数组指定行时非目标行数据意外被修改问题
JS二维数组修改单行列值时其他行同步被修改问题
问题复现
需求为修改二维数组table.pos第50行的元素值,数组元素默认值为-1,实现代码如下:
let rowUp = table.pos[51] for (let i in rowUp){ process.stdout.write(rowUp[i].val+'') } process.stdout.write('\n') let rowSet = table.pos[50] for (let i in rowSet){ rowSet[i].val = 0 process.stdout.write(rowSet[i].val+'') } process.stdout.write('\n') let rowDn = table.pos[49] for (let i in rowDn){ process.stdout.write(rowDn[i].val+'') }
实际运行输出不符合预期:
-1-1-1-1-1-1-1-1-1-1 0000000000 0000000000
预期输出应为:
-1-1-1-1-1-1-1-1-1-1 0000000000 -1-1-1-1-1-1-1-1-1-1
故障原因
问题出在二维数组的初始化逻辑:初始化时在循环外提前创建了cellData实例,后续循环只是把同一个对象的引用赋值给了所有数组位,导致整个二维数组的所有单元格都指向同一个内存地址的对象。修改第50行元素的val属性时,本质是修改这个公共对象的属性,所有引用该对象的行取值都会同步变化。
错误初始化代码如下:
const cellData = await new cellSchema() for (let posZ = 0; posZ < 100; posZ++) { let row = [] for (let posX = 0; posX < 100; posX++) { row[posX] = cellData } table.pos[posZ] = row }
修复方法
将cellData实例的创建逻辑移入内层循环,每一个单元格都生成独立的对象实例,从根源上避免对象引用共用的问题。修正后的初始化代码:
for (let posZ = 0; posZ < 100; posZ++) { let row = [] for (let posX = 0; posX < 100; posX++){ const cellData = await new cellSchema() row[posX] = cellData } table.pos[posZ] = row }
内容的提问来源于stack exchange,提问作者user19305209
相关产品推荐
相关产品推荐

