Javascript变量引用异常:使用[...all]浅拷贝仍修改原始对象属性
问题根因说明
该现象是JavaScript浅拷贝特性的原生表现,和Angular框架无关:
- 数组展开语法
[...all]仅会创建新的数组实例,数组内存储的仍是all_obj对应子对象的内存引用,没有生成新的子对象副本。 - 代码中
map回调内直接对dp.value赋值的操作,本质是通过引用直接修改了all_obj中的原始子对象属性,因此原对象会同步更新。
该逻辑和最终排查结论一致:并非数据回溯传播导致,就是对象引用共享带来的修改同步。
修复方案
有两种常用的修复方式,可根据业务场景选择:
方案1:遍历时返回新对象(推荐,性能最优)
不对原对象做任何修改,在map回调中返回新构造的对象,完全隔离原引用:
datapoints: [...all].map((dp: brand_datapoint) => { return { ...dp, value: +(dp.value / dp.volume).toFixed(2) }; })
方案2:先深拷贝所有数据再修改
如果子对象层级较深、结构复杂,可以先深拷贝再做修改:
// 子对象均为普通JSON结构时,可用JSON序列化快速实现深拷贝 datapoints: JSON.parse(JSON.stringify(all)).map((dp: brand_datapoint) => { dp.value = +(dp.value / dp.volume).toFixed(2); return dp; }) // 存在日期、函数等特殊类型时,可使用lodash.cloneDeep等成熟深拷贝工具实现
内容的提问来源于stack exchange,提问作者Samuel Pollard
相关产品推荐
相关产品推荐

