关于Object.assign()嵌套对象修改影响原对象的技术疑问
为什么Object.assign()修改嵌套对象会影响原对象?
核心原因很直接:Object.assign() 执行的是浅拷贝,而非深拷贝。要搞懂这个问题,得先理清JavaScript里两种数据类型的底层处理逻辑:
1. 原始类型与引用类型的本质区别
JavaScript的数据类型分为两类,赋值逻辑完全不同:
- 原始类型:string、number、boolean、null、undefined、symbol、bigint,这类值直接存储在栈内存中,赋值时会完整复制值本身,两个变量互不关联。
- 引用类型:对象(包括普通对象、数组、函数等),这类值的实际数据存在堆内存,变量里仅存储指向堆内存的引用地址,赋值时只会复制这个地址,两个变量最终指向同一个堆内存对象。
2. 对应你的代码逐段分析
看这段初始化代码:
const obj1 = { a: 0, b: { c: 0 } }; const obj2 = Object.assign({}, obj1);
- 对于
obj1.a(值为0,属于number原始类型):Object.assign会把0这个值直接复制给obj2.a,此时obj1.a和obj2.a是两个独立的栈内存值,所以后续修改其中一个,另一个不会受影响。 - 对于
obj1.b(是一个嵌套对象,属于引用类型):Object.assign只复制了obj1.b的引用地址给obj2.b,也就是说obj1.b和obj2.b指向堆内存里的同一个对象。当你执行obj2.b.c = 3时,本质是修改了这个共享对象的属性,自然obj1.b.c也会同步变化。
3. 实现真正独立的深拷贝方法
如果需要让嵌套对象也完全独立,可使用这些方案:
- 简易版(有局限):用
JSON.parse(JSON.stringify(obj)),但无法拷贝函数、Symbol类型、循环引用的对象。const obj2 = JSON.parse(JSON.stringify(obj1)); - 自定义递归深拷贝:遍历对象所有属性,遇到引用类型就递归拷贝,原始类型直接复制。
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; } const obj2 = deepClone(obj1);
内容的提问来源于stack exchange,提问作者Mohammed
相关产品推荐
相关产品推荐

