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时:- 先通过
newUser当前的引用找到原user对象,取出它的address属性——这个属性存的是指向嵌套地址对象({country: "England", city: "Manchester"})的引用。 - 把这个引用赋值给
newUser,此时newUser不再指向原user对象,而是直接指向堆里的那个嵌套地址对象。 - 这个过程完全没有创建新对象,只是改变了
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
相关产品推荐
相关产品推荐

