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

JavaScript对象引用疑问:为何嵌套属性修改会同步至原对象?

JavaScript对象赋值与引用的核心原理

要搞懂你遇到的两种情况,关键得明白JavaScript里引用类型变量的存储逻辑:对象、数组这类引用类型,变量本身并不直接存对象内容,而是存一个指向堆内存中对象的地址引用。下面分两种情况拆解:

1. 重新赋值obj2为nestedObj,仅obj2变化的原因

先看对应代码:

const obj1 = {
  nestedObj: { foo2: 'bar' }
};
let obj2 = obj1; // 第一步赋值
obj2 = obj2.nestedObj; // 重新赋值obj2
  • 第一步obj2 = obj1:把obj1里存储的「外层对象的引用地址」复制给了obj2,此时obj1和obj2指向堆内存中同一个外层对象。
  • 第二步obj2 = obj2.nestedObj:这是给obj2变量重新赋值,把它存储的引用地址换成了「nestedObj对象的地址」。这时候obj1的引用地址还是指向原来的外层对象,两者指向的对象已经不一样了,所以只有obj2发生变化,obj1不受影响。

2. 修改obj2的foo2,obj1同步变化的原因

对应代码:

const obj1 = {
  nestedObj: { foo2: 'bar' }
};
let obj2 = obj1;
obj2.nestedObj.foo2 = 'updated'; // 修改属性
  • obj2 = obj1后,两者指向同一个外层对象,而外层对象里的nestedObj也是一个引用类型,它的地址同样被存在外层对象中。
  • 当执行obj2.nestedObj.foo2 = 'updated'时,你并没有修改obj2变量里的引用,而是顺着这个引用找到堆内存中的外层对象,再找到它的nestedObj引用指向的对象,最后修改这个对象的foo2属性。
  • 因为obj1指向的外层对象和obj2的是同一个,它的nestedObj引用也指向同一个子对象,所以obj1访问nestedObj.foo2时,看到的就是修改后的值。

关键区分:变量重新赋值 vs 对象属性修改

  • 变量重新赋值(比如obj2 = xxx):只是改变变量自身存储的引用地址,和原对象无关,其他指向原对象的变量不会受影响。
  • 对象属性修改(比如obj2.key = xxx):是直接在堆内存中修改对象本身,所有指向该对象的变量都会同步看到变化。

另外纠正一个常见误区:JavaScript是按值传递,但这里的「值」对于引用类型来说是「引用地址」。不是所谓的“引用传递”,因为赋值时是把引用地址复制了一份给新变量,两个变量的引用是独立的,只是指向同一个对象而已。

内容的提问来源于stack exchange,提问作者Marcelo Alarcon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 01:11:32