Все достаточно просто, хоть и не совсем очевидно.
Выражение:
foo.x = foo = {n: 2};
равносильно:
foo.x = (foo = {n: 2});
Мы присваиваем объекту по идентификатору foo свойство x, которое равно результату операции присваивания идентификатору foo ссылки на объект
{ n: 2 }
.
Чтобы в этом убедиться достаточно добавить переменную bar, присвоить ей начальное значение foo и вывести в конце:
let foo = {};
const bar = foo;
foo.x = (foo = {n: 2});
console.log(foo.x === undefined); // true
console.log(bar); // { x: { n: 2 } }
console.log(bar.x === foo); // true
Ключевые отличия операций присваивания, которые важно понимать:
foo.x =
- присваивание свойства конкретному объекту. На момент вызова в нашем примере это
{}
.
foo =
- присваивание значения самому идентификатору foo. Это может быть примитив, ссылка на объект или функцию. В нашем случае это объект
{ n: 2 }
.