JavaScript修改复制的数组时原数组同步变动,如何修改副本不影响原数组
问题成因
你使用的slice()、扩展运算符[...arr]、slice(0)都属于浅拷贝,仅会复制数组的第一层结构。由于你传入的cid是二维数组,第一层的每一项仍然是数组(引用类型值),浅拷贝后新数组tempArr的子数组和原数组cid的子数组指向完全相同的内存地址,你修改tempArr[i][1]本质是修改了同一块内存里的内容,因此原数组会同步变化。
解决方案
针对你的二维数组场景,有3种常用实现方案:
方案1:手动二维拷贝(性能最优)
遍历第一层数组时,同步拷贝每一个子数组:
function checkCashRegister(price, cash, cid) { let payBackAmount = cash - price; // 遍历第一层时拷贝每个子数组 let tempArr = cid.map(item => [...item]); for (let i = 0; i < tempArr.length; i++) { tempArr[i][1] = 0; } console.log("cid is", cid); // 原数组不会发生变化 } checkCashRegister(19.5, 20, [ ["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100], ]);
方案2:JSON序列化反序列化(适用无特殊类型的场景)
如果数组里仅包含字符串、数字、布尔值、普通对象/数组这类可序列化值,直接用JSON方法做深拷贝:
let tempArr = JSON.parse(JSON.stringify(cid));
注意该方案无法处理函数、Symbol、undefined、循环引用等特殊场景,你当前的使用场景完全兼容。
方案3:原生深拷贝方法(兼容性允许时优先)
现代浏览器和Node.js环境支持原生structuredClone方法,支持深拷贝绝大多数类型,适用范围比JSON方案更广:
let tempArr = structuredClone(cid);
内容的提问来源于stack exchange,提问作者Ishan Sahu
相关产品推荐
相关产品推荐

