Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two assignments in one line [duplicate]

Tags:

javascript

var

Let's say we start with this:

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

In JavaScript, what is the order in which the following assignments are carried out:

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

When I looked up answers to this I found several that seemed to suggest that assignments happen from RIGHT TO LEFT, eg:

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

In which case we would expect:

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

However what I see in the console when I actually do this suggests that assignments actually happen from LEFT TO RIGHT:

console.log(foo) //{n:2} console.log(bar) //{n:1, x:Object} --> The {n:1} obj gets an 'x' property, and foo gets reassigned to a new object {n:2}

Can someone clarify for me the order of operations when there are multiple assignments in one line?

Also, what is the underlying rule that distinguishes the above scenario from a situation like the following: Multiple variable assignments in one row

Some of the answers in the above question claim that assignments of primitives are carried out RIGHT TO LEFT...

like image 470
ionox0 Avatar asked Dec 11 '22 23:12

ionox0


2 Answers

The assignment does go from right to left. It's just that the resolution of foo.x happens before the assignment. (Ecma Standard 11.13.1 Simple Assignment)

Think of it like this. Before the assignment, foo and bar happen to be pointing to the same object in memory. (We'll call it inMemoryObject).

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

We then refer to foo.x at the beginning of an assignment method. Because foo.x doesn't exist, the placeholder gets created, ready to be assigned to.

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

Once the variable is created, then the right-to-left assignment process begins, assigning to inMemoryObject.x. At the end of the assignment process, foo no longer points to inMemoryObject, but bar still does.

bar --|
      |---> inMemoryObject { 
                              n:1, 
                              x: --| 
foo --|                     }      |
      |                            |
      |----------------------------|--- secondInMemoryObject {
                                                                n:2
                                                             }
like image 73
Andrew Shepherd Avatar answered Dec 20 '22 13:12

Andrew Shepherd


The assignments happen from right to left, but the assignment target evaluation happens from left to right.

Basically the whole expression starts evaluating from left to right, but the actual assignment needs the return value from the right side. So the assigment itself has to happen after retuning the value of the evaluation of the right side.

like image 40
Stefan Haustein Avatar answered Dec 20 '22 13:12

Stefan Haustein