JavaScript中函数传参及数组push时如何避免原数组值被修改
问题根源
cid中的每一项都是数组类型(属于JS引用类型),直接执行change.push(cid[j])时,存入change的是原cid[j]的内存引用,而非独立复制的新数组。后续修改cid[j][1]本质是修改同一块内存空间的值,因此change中对应的数值也会同步变化。
解决方法
只要在往change中存入数据时,创建cid[j]的独立副本即可。由于cid[j]是仅包含基础类型值的一维数组,使用浅拷贝就能完全满足需求,拷贝可以用以下任意一种方式:
- 扩展运算符:
[...cid[j]] - 数组
slice方法:cid[j].slice() - 手动构造新数组:
[cid[j][0], cid[j][1]]
把原代码中两处change.push(cid[j])替换为change.push([...cid[j]])即可解决同步修改的问题。
补充优化点:toFixed()方法返回的是字符串类型,直接参与数值计算可能出现隐式类型转换异常,建议手动转成数值类型再赋值给toPay。
修改后的完整代码
function checkCashRegister(price, cash, cid) { let j = 0; let change = []; var currency = { 'ONE HUNDRED': 100, TWENTY: 20, TEN: 10, FIVE: 5, ONE: 1, QUARTER: 0.25, DIME: 0.1, NICKEL: 0.05, PENNY: 0.01 } let toPay = cash - price; let index = 0; for (let j = cid.length - 1; j >= 0; j--) { if (toPay == 0) { break; } if (cid[j][1] <= toPay && cid[j][1] !== 0) { // 存入副本而非原引用 change.push([...cid[j]]); toPay = toPay - cid[j][1]; cid[j][1] = 0; } if (cid[j][1] > toPay) { if (currency[cid[j][0]] < toPay) { index = ~~(toPay / currency[cid[j][0]]); // 把toFixed返回的字符串转成数值,避免类型异常 toPay = Number((toPay - (index * currency[cid[j][0]])).toFixed(2)); cid[j][1] = (index * currency[cid[j][0]]); // 存入副本而非原引用 change.push([...cid[j]]); } } } return change; }
内容的提问来源于stack exchange,提问作者Fransedo Ravelino
相关产品推荐
相关产品推荐

