如何实现对象深拷贝?Object.assign浅拷贝修改数组仍影响原对象
解决浅拷贝导致引用类型属性同步修改的问题
这是个非常常见的浅拷贝坑!我来帮你彻底解决这个问题~
为什么会出现这个问题?
你用的Object.assign({}, oldObj)属于浅拷贝:它只会复制对象的顶层基本类型属性(比如你的X:10),但对于数组Y这种引用类型的属性,它复制的仅仅是指向该数组的内存地址,而不是数组本身。也就是说,newObj.Y和oldObj.Y其实指向的是同一个数组,你修改其中一个,另一个自然会跟着变化。
几种可行的解决方案
1. 手动处理引用类型属性(适合简单对象结构)
如果你的对象结构不复杂,可以单独对数组属性做拷贝,避免引用共享:
let oldObj = {X:10, Y:[]}; let newObj = { ...oldObj, // 展开顶层属性 Y: [...oldObj.Y] // 单独拷贝数组,生成新的数组实例 }; newObj.Y.push(3.29231994); console.log(oldObj); // 输出 {X:10, Y:[]},原对象不受影响
2. JSON序列化反序列化(快捷但有局限性)
如果你的对象里没有函数、Symbol、undefined或循环引用这类特殊数据,这种方法最省事:
let oldObj = {X:10, Y:[]}; let newObj = JSON.parse(JSON.stringify(oldObj)); newObj.Y.push(3.29231994); console.log(oldObj); // 输出 {X:10, Y:[]}
⚠️ 注意:这种方法会丢失函数、Symbol、undefined等无法被JSON序列化的数据,遇到循环引用还会报错。
3. 手写递归深拷贝函数(适合复杂对象结构)
如果你的对象有嵌套的对象/数组,或者包含特殊类型,手写深拷贝函数能提供更强的可控性:
function deepClone(obj) { // 非对象类型直接返回 if (obj === null || typeof obj !== 'object') return obj; // 处理数组 if (obj instanceof Array) { return obj.map(item => deepClone(item)); } // 处理普通对象 const clonedObj = {}; for (let key in obj) { if (obj.hasOwnProperty(key)) { clonedObj[key] = deepClone(obj[key]); } } return clonedObj; } let oldObj = {X:10, Y:[]}; let newObj = deepClone(oldObj); newObj.Y.push(3.29231994); console.log(oldObj); // 输出 {X:10, Y:[]}
这个方法可以处理大部分复杂场景,包括多层嵌套的对象和数组。
内容的提问来源于stack exchange,提问作者hashtabe_0
相关产品推荐
相关产品推荐

