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

为何对象类型变量始终与对象值同步?解析JS代码片段B的赋值逻辑

为什么JavaScript中引用类型赋值后修改原对象会影响新变量?

嘿,这个问题刚好戳中了JavaScript里原始类型和引用类型赋值的核心区别,咱们一步步把它捋明白~

先把你提到的两个代码片段放出来方便对比:

代码片段A(原始类型)

x = 5; y = x; x = 6; console.log(x); console.log(y);
// 输出:6 5

代码片段B(引用类型)

x = {one: 5}; y = x; x.one = 6; console.log(x); console.log(y);
// 输出:{one: 6} {one: 6}

先搞懂片段A的逻辑(原始类型值拷贝)

对于数字、字符串这类原始类型,变量存储的是实际的值:

  • 执行x = 5时,JavaScript会在栈内存里给x分配一个位置,把值5存在这里。
  • 执行y = x时,会把x存储的5完整拷贝一份,放到y的栈内存位置里。
  • 之后x = 6,只是把x的栈位置里的值改成了6,和y的那份拷贝完全没关系,所以最后log出来x是6,y是5。

再拆解片段B的核心(引用类型地址拷贝)

而对象、数组这类引用类型,逻辑就完全不一样了:

  1. 当你执行x = {one: 5}时,JavaScript会在堆内存里创建这个对象{one:5}(因为对象可能体积较大,栈内存放不下),然后把这个对象在堆里的内存地址(比如0x123)赋值给变量x——也就是说x的栈内存里存的不是对象本身,而是指向对象的“门牌号”。
  2. 执行y = x时,并不是把堆里的对象拷贝一份给y,而是把x存的那个“门牌号”(0x123)拷贝给了y。现在x和y的栈内存里存的是同一个门牌号,它们都指向堆里的同一个对象。
  3. 然后x.one = 6这个操作,不是修改x的门牌号,而是顺着x的门牌号找到堆里的那个对象,把对象的one属性改成了6。因为y和x指向的是同一个对象,所以当你log(y)的时候,顺着y的门牌号找到的也是这个已经被修改过的对象,自然就会输出{one: 6}。

回应你的疑惑

你之前以为“在初始化y的时刻,x的值仍是{one:5},y应该等于{one:5}”,这个误区在于:你把y = x理解成了拷贝对象本身,但实际上拷贝的只是指向对象的地址。在y = x的瞬间,x和y确实都指向{one:5},但后续修改的是这个共享的对象,而不是x的地址,所以y自然能看到对象的变化。

打个比方:x和y都拿着同一个仓库的钥匙,x去仓库里把里面的东西换成了6,y再去开仓库门,看到的肯定也是换后的东西——而不是x复制了一个新仓库给y。

总结关键点

  • 原始类型赋值是值拷贝:变量存实际值,修改一个不影响另一个。
  • 引用类型赋值是地址拷贝:变量存堆内存地址,多个变量指向同一个对象,修改对象属性会影响所有指向它的变量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 09:37:31