2015-05-11 4 views
4

Допустим, мы начнем с этого:Два задания в одной строке

var foo = {n:1}; var bar = foo;

В JavaScript, что порядок, в котором следующие задания выполняются:

foo.x = foo = {n:2};

Когда Я искал ответы на это, я нашел несколько, которые, казалось, предполагали, что назначение происходит от ПРАВА НА ЛЕВУЮ, например:

foo = {n:2}; foo.x = foo;

В этом случае можно было бы ожидать:

console.log(foo) //{n:2, x:Object} - (a circular reference back to foo)

Однако то, что я вижу в консоли, когда я на самом деле это говорит о том, что задания на самом деле произошло слева направо:

console.log(foo) //{n:2} console.log(bar) //{n:1, x:Object} - -> Объект {n: 1} получает свойство «x», а foo переназначается на новый объект {n: 2}

Может ли кто-нибудь уточнить для меня орду r операций, когда в одной строке есть несколько назначений?

Кроме того, что основное правило, которое отличает выше сценарий от такой ситуации, как следующее: Multiple variable assignments in one row

Некоторые из ответов в приведенном выше п вопроса, что задания примитивов выполняются справа налево .. .

ответ

12

Назначение выполняется справа налево. Это просто, что разрешение foo.x происходит до назначения. (Ecma Standard 11.13.1 Simple Assignment)

Подумайте об этом. Перед назначением foo и bar указывают на один и тот же объект в памяти. (Назовем это inMemoryObject).

foo --| 
bar --| 
     |---> inMemoryObject { 
           n:1 
          } 

Затем обратитесь к foo.x в начале способа назначения. Поскольку foo.x не существует, создатель будет создан, готовый к назначению.

foo --| 
bar --| 
     |---> inMemoryObject { 
           n:1, 
           x: undefined 
          } 

После создается переменная, а затем начинается процесс присвоения справа налево, сопоставляя inMemoryObject.x. В конце процесса назначения foo больше не указывает на inMemoryObject, но bar все еще делает.

bar --| 
     |---> inMemoryObject { 
           n:1, 
           x: --| 
foo --|      }  | 
     |       | 
     |----------------------------|--- secondInMemoryObject { 
                   n:2 
                  } 
+1

Как вы это знаете? – fuzz

+0

Нет абсолютно никакой вещи, как объекты «заполнителя». –

+1

Перечитав свой ответ и [spec] (http://es5.github.io/#x11.13.1), я заметил, почему вы сделали это вместе с фатальный недостаток в моем собственном ответе. Нет «объекта-заполнителя», но вместо этого * ссылка * на свойство 'x' объекта in-memory. –

1

Назначения выполняются справа налево, но целевая оценка назначения выполняется слева направо.

В основном, все выражение начинает оценивать слева направо, но для фактического назначения требуется возвращаемое значение с правой стороны. Таким образом, сам настрой должен произойти после перенастройки значения оценки правой стороны.

+0

", но назначение целевой оценки происходит слева направо.»- то, как вы используете« оценку », вводит в заблуждение. Если цели назначения были оценены слева направо, тогда это занесло бы в журнал' undefined': http://jsfiddle.net/w8cbhdub/ –

Смежные вопросы