You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 05:03:36