Как работает литеральное назначение и ссылка объекта Javascript?

У меня простой вопрос

let obj1 = {};
obj2= obj1;`

Здесь obj1 и obj2 ссылаются на один и тот же объект в памяти, то есть obj1===obj2 --> true. Таким образом, по этой логике любая операция над obj2 повлияет на obj1.

Теперь, если я назначу свойство obj2

let obj1 = {};
obj2 = obj1;

obj2['a'] = {};
obj2 = obj2['a']; // why this operation didn't change obj1, if they are referencing the same object ?
console.log(obj1); // -- > { a: {} };
console.log(obj2); // -- > {};

теперь obj1===obj2 --> false почему это ?

Также Как получилось obj2 = {} is different then obj2 = obj2['a'] ?

Скриншот для пояснения себя

введите здесь описание изображения

Заранее благодарны за Вашу помощь.


person niraj    schedule 22.12.2020    source источник
comment
obj2 = obj2.a переназначает obj2, чтобы он больше не указывал на obj1.   -  person Aplet123    schedule 22.12.2020
comment
Потому что, когда вы делаете obj2 = obj2[a], вы переназначаете имя идентификатора obj2 на совершенно новое значение, а не просто добавляете свойство.   -  person Andrew Li    schedule 22.12.2020
comment
для объекта.. равенство определяет, на что он указывает.. на другие вещи, такие как строки или числа.. это просто значения   -  person The Bomb Squad    schedule 22.12.2020
comment
Спасибо @Aplet123 Это тот случай, когда obj2 = {}. Однако, если мы делаем obj2['b'] = {}; obj2 = obj2['b']; , это также изменяет obj1 на {'a':{'b':{}}}. Эта часть меня смущает.   -  person niraj    schedule 22.12.2020
comment
obj2.b = {} не переназначает obj2, а присваивает значение свойству obj2, то есть оно по-прежнему указывает на obj1, то есть изменения будут отражены в obj1. obj2 = obj2.b не имеет значения.   -  person Aplet123    schedule 22.12.2020
comment
@niraj Почему тебя это смущает? После obj2.a = {}; obj2 = obj2.a; obj1 указывает на тот же объект, что и раньше. obj2 нет; он указывает на свойство a объекта, на который указывает obj1. obj1 === obj2.a. Затем, если вы добавите свойство b к obj2, вы просто вложите другое свойство в obj2. Поскольку obj1 по-прежнему указывает на «корневой» объект, естественно, он отражает все изменения.   -  person Sebastian Simon    schedule 22.12.2020
comment
@niraj Переход через эта визуализация также может помочь прояснить некоторые вещи   -  person Nick Parsons    schedule 22.12.2020
comment
Вы путаете назначение переменной с назначением свойства объекта.   -  person StackSlave    schedule 22.12.2020
comment
@NickParsons Это очень полезно. Большое спасибо!!   -  person niraj    schedule 22.12.2020


Ответы (2)


Для объектов оператор присваивания = присваивает ссылку на объект.

So in:

let obj1 = {};
let obj2 = obj1;

оба obj1 и obj2 ссылаются на один и тот же объект. В настоящее время:

obj2['a'] = {};

создает новое свойство a и присваивает ему значение, являющееся ссылкой на новый объект. Поскольку и obj1, и obj2 ссылаются на один и тот же объект, вы также обнаружите:

obj2.a === obj1.a

Но потом:

obj2 = obj2['a']; // why this operation didn't change obj1, if they are referencing the same object ?

Теперь вы назначили другой объект для obj2, так что теперь он ссылается на новый объект, изначально назначенный obj2.a, и:

obj1.a === obj2;

Итак, obj1 был изменен (или, точнее, был изменен объект, на который ссылается obj1).

Некоторый код:

// obj1 and obj2 reference the same object
let obj1 = {};
let obj2 = obj1;
console.log('obj2 === obj1     ' + (obj2 === obj1)); // true

// Assign new object to obj2.a
obj2['a'] = {};

// Affects obj1
console.log('obj2.a === obj1.a ' + (obj2.a === obj1.a)); // true

// Assign new object to obj2
obj2 = obj2['a'];

// obj2 now references a different object to obj1
console.log('obj1 === obj2     ' + (obj1 === obj2)); // false

// obj1.a still references new object
console.log('obj1.a === obj2   ' + (obj1.a === obj2)); // true

person RobG    schedule 22.12.2020

obj2 — это объект, obj2[a] — другой объект. Результат сравнения двух объектов ложный.

 {} === {}    // false
person 7-month    schedule 22.12.2020