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

JavaScript嵌套对象赋值的内存机制及对原对象的影响解析

嵌套对象赋值的内存变化与引用影响解析

先看你提供的代码:

let user = {
    name: "John",
    age: 30,
    address: {
        country: "England",
        city: "Manchester"
    }
}

let newUser = user; // shallow copy

newUser = newUser.address; // 这里把嵌套对象赋值给newUser,内存里发生了什么?有没有创建新对象?和直接赋值字面量的区别是什么?

newUser.city = "London" // 修改newUser的city会影响原user对象,为什么?

console.log("newUser", newUser);
console.log("user", user);  

问题1:执行newUser = newUser.address时的内存变化,与字面量赋值的区别

首先得明确:JavaScript里对象存在堆内存中,变量(比如user、newUser)存储的不是对象本身,而是指向堆内存中对象的引用地址。

  • 执行newUser = user后,newUser和user指向堆里同一个大对象(包含name、age、address的那个对象)。
  • 当执行newUser = newUser.address时:
    1. 先通过newUser当前的引用找到原user对象,取出它的address属性——这个属性存的是指向嵌套地址对象({country: "England", city: "Manchester"})的引用。
    2. 把这个引用赋值给newUser,此时newUser不再指向原user对象,而是直接指向堆里的那个嵌套地址对象。
    3. 这个过程完全没有创建新对象,只是改变了newUser变量存储的引用地址。
  • 和newUser = {country:"testing", city: "xxx"}的核心区别:
    后者会在堆内存里创建一个全新的独立对象,再把新对象的引用赋值给newUser。这个新对象和原user.address没有任何关联,是两块完全分开的内存。

问题2:修改newUser.city为何影响原user对象

执行newUser = newUser.address后,newUser和user.address指向的是堆内存里同一个地址对象。你修改newUser.city,本质是通过引用找到堆里的那个对象,直接修改它的city属性值。而user.address存的也是同一个对象的引用,所以当你打印user时,看到的就是修改后的属性值——因为对象本身在堆里已经被改动了。

简单说:两个变量指向同一个对象,改其中一个的属性,另一个自然能看到变化,因为改的是同一个内存里的对象本身。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 18:36:41