这似乎是一件很普通的事情,但有点令人困惑。我被困在两个场景,并试图了解这里正在发生的事情。
场景1
let obj2 = {b:{c:{d:4}}}
let obj1 = {a:obj2['b']}
obj2['b'] =9
console.log(obj1)// --- > { a: { c: { d: 4 } } }
console.log(obj2)// --- > { b: 9 }
当我更改obj2['b']的值时,我期望obj1也会发生变化,因为obj1['a']也引用了相同的内存位置,但它没有。
场景2
let obj2 = {b:{c:{d:4}}}
let obj1 = {a:obj2['b']}
obj2['b']['c'] =9
console.log(obj1)// --- > { a: { c: 9 } }
console.log(obj2)// --- > { b: { c: 9 } }
当我更改obj2['b']['c']值时,obj1['a']['c']的值也会发生变化,因为它引用的是相同的内存位置。据我所知,这是我期待的行为。
我想要一个关于场景1的解释,为什么它不改变obj1的值?
发布于 2020-10-02 15:42:33
我认为一些图表在这里可能有用,以帮助显示正在发生的事情。在第一个代码块中,在执行前两行代码之后,您的情况如下:

注意,来自两个对象的两个键b和a都在内存中存储对同一个对象的引用。一旦执行第三行,您将得到以下情况:

如您所见,用于b的obj2键现在保存值9,而不再保存对对象的引用。但是,obj1仍然保存对对象的引用。因此,当您记录obj1时,仍然会看到嵌套对象的c和d属性。
然而,对于场景二,您的情况有点不同。在执行前两行代码之后,您将得到与这个答案的第一个图像中所示的相同的图表。但是,一旦执行第3行,您的关系图将更改为:

在这种情况下,对象1和对象2的键a和b仍然在内存中存储对同一个对象的引用(与前面的场景不同)。这一次,它们在内存中都指向的对象被更新,以便c键处的值不再是对内存中的对象的引用,而是值9。因此,当您同时记录obj1和obj2时,您会看到相同的嵌套对象。
上面的图表是由吡虫啉在ES6可视化器下生成的。
发布于 2020-10-02 15:14:19
在场景1中,您创建了一个对象( obj2 ),该对象的属性b被分配给一个新对象,然后创建了一个新对象(obj1),它的属性a是对obj2中b属性中相同对象的引用。更改obj2中的b属性后,仅在obj1 1的a属性中引用其中的对象。基本上,对象在堆内存中,并且您将它们的地址存储在属性中,因此一旦将属性更改为不同的东西,而不是删除它,您就停止引用对象,如果没有其他引用对象,GC将最终删除它。
https://stackoverflow.com/questions/64173768
复制相似问题