使用Object.assign拷贝对象后修改克隆对象原对象也变更的问题
问题原因
Object.assign属于浅拷贝,仅会拷贝对象的第一层属性,你声明的original对象里appList是引用类型的数组,浅拷贝后clone.appList和original.appList指向同一块内存地址,数组内部的所有app对象也都是同一个引用。- 你在
map回调中直接修改了app.serviceList属性,这里的app就是原original.appList中的对象引用,直接修改它的属性自然会同步变更到原对象上。即使你给clone.appList赋值了新的过滤后数组,数组内的app对象依旧是原对象的引用,修改属性会直接影响原对象。
解决方案
有两种常用的解决思路,按需选择即可:
方案1:操作时拷贝内层对象,不修改原引用
在map处理时先拷贝当前app对象,再修改拷贝出来的新对象,避免触碰原对象的引用:
clone.appList = clone.appList.filter(app => app.appId == 'app-1').map( app => { // 先浅拷贝当前app对象,后续仅修改新对象 const newApp = {...app}; if(newApp.serviceList && newApp.serviceList.length) { newApp.serviceList = newApp.serviceList.filter(service => { const { mList } = service; return mList && mList.length; }); } return newApp; });
方案2:初始化克隆时直接做深拷贝
如果对象层级较深、改动点多,可以直接对original做深拷贝,后续所有操作都在完全独立的克隆对象上执行:
- 无特殊类型(函数、Symbol、循环引用等)的普通对象可以用
JSON.parse(JSON.stringify(original)) - 现代浏览器/Node.js环境可以用原生结构化克隆API
structuredClone(original) - 也可以直接使用lodash的
_.cloneDeep工具方法
示例:
// 用原生结构化克隆做深拷贝 const clone = structuredClone(original);
内容的提问来源于stack exchange,提问作者kiranbabu
相关产品推荐
相关产品推荐

