问题描述
我读了一个片段,很困惑,找不到解释的规则或原则,输出是 Malibu
,为什么不是 London
,adress: sherlock.address
中的 let john = { surname: 'Watson',address: sherlock.address };
是将sherlock.adress
的值赋给john.address
,但不能用sherlock.adress
覆盖john.address
。我怎么能弄乱我的头发。
let sherlock = {
surname: 'Holmes',address: { city: 'London' }
};
let john = {
surname: 'Watson',address: sherlock.address
};
john.surname = 'Lennon';
john.address.city = 'Malibu';
console.log(sherlock.address.city); //
解决方法
关于对象的令人困惑的事情是 PRIMITIVES 与 OBJECTS 的行为不同
当您“读取”一个原始字符串(或数字或布尔值)时,例如 sherlock.surname
,您正在获取它的值,即您正在接收一个副本 原始数据。所以如果你这样做
eureka = {surname: sherlock.surname}
那么您可以想象eureka
收到原始“福尔摩斯”的“影印本”。您的计算机中将存储两个字符串“Holmes”。你可以改变一个,另一个不会改变,因为它们是分开的。
但是当您“读取”一个对象时,例如sherlock
,您应该想象您只获取了一个指向原始对象的指针。不是它的副本,而是通过计算机到达相同内存位置的另一条路径。所以如果你这样做
eureka = sherlock
那么此语句不会在计算机内创建字符串“Holmes”的第二个副本。计算机的内存中只有一个“福尔摩斯”字符串。它位于这样的对象中:{surname: "Holmes"}
。 sherlock
指向那个对象,而 eureka
指向同一个对象。因此,当您编辑 eureka
或 sherlock
的某些属性时,两个变量的相应属性将同时更改。两个变量名称 eureka
和 sherlock
指向内存中的同一个对象。
以上内容非常基本(请原谅我的双关语!)但是当您引用对象中的对象或对象中的原始对象时,它变得棘手。单独看赋值语句您无法判断您正在阅读的内容是原始内容还是对象。你必须知道结构才能知道。
let a={b:{c:1}}
let w = a // This makes "w" an alias for the same single object,to which "a" also points
w.b.c=2
console.log(a)
// {
// "b": {
// "c": 2
// }
// }
w.b = 3
console.log(a)
// {
// "b": 3
// }
在此处注释您的脚本
let sherlock = {
surname: 'Holmes',address: { city: 'London' }
};
let john = {
surname: 'Watson',address: sherlock.address // Here,you are not COPYING the { city: 'London'},you are pointing at the same object in memory,i.e. the "address" property of sherlock.
};
john.surname = 'Lennon';
john.address.city = 'Malibu'; // When you go to john.address,you are now pointing into the piece of memory that sherlock is also using to store his address,so when you put a value into 'city',that will show up whether you access it as john.address or sherlock.address
console.log(sherlock.address.city);