Я просматривал отрывок из здесь
var foo = {n: 1};
var bar = foo;
foo.x = foo = {n: 2};
Когда я регистрирую файл foo.x, он говорит, что он не определен. Почему это так? Я ожидал, что это будет {n: 2}
Я просматривал отрывок из здесь
var foo = {n: 1};
var bar = foo;
foo.x = foo = {n: 2};
Когда я регистрирую файл foo.x, он говорит, что он не определен. Почему это так? Я ожидал, что это будет {n: 2}
Значения присваиваются слева направо, поэтому происходит следующее:
foo.x = {n: 2};
, в результате чего foo будет {n: 1, x: {n: 2}}
тогда foo присваивается новое значение
foo = {n: 2};
, который заменяет его на {n: 2}
.
Значение foo.x
оценивается перед обоими присвоениями, поэтому оно ссылается на свойство x
старого объекта foo
. Это поведение определяется 12.14.4 Семантика времени выполнения: оценка (ES6, последний черновик), в котором говорится, что левая часть оператора присваивания (цель присваивания) должна оцениваться перед правой частью оператора присваивания. оператор присваивания (присваиваемое значение).
Итак, эти три результата имеют один и тот же результат:
var foo = {n: 1};
var bar = foo;
foo.x = foo = {n: 2};
console.log(foo, bar)
var foo = {n: 1};
var bar = foo;
bar.x = foo = {n: 2};
console.log(foo, bar)
var foo = {n: 1};
var bar = foo;
foo.x = (foo = {n: 2});
console.log(foo, bar)
Но присваивание связывается справа налево:
foo.x = foo = {n: 2};
эквивалентно броскамfoo.x = (foo = {n: 2});
и(foo.x = foo) = {n: 2};
.Вот это да. Оба ваших объяснения кажутся верными, но теперь я не понимаю, что такое правильный поток. Может кто-нибудь разобрать это. Я вижу ответ @AndrewSvietlichnyy более оправданным
Я думаю, что его ответ правильный, но он приводит к поведению, которое я объяснил