0

Let's evaluate this code for swapping two variables :

var a = 5, b = 3; 
a = ( a -( b = ( a = a+b ) - b ) );

I was expecting that new value of a should be 3 and value of b should be 5. But I got values as a = 0 and b = 5;

I went and read the EcmaScript Arithmetic expression and found that this will be evaluated from left-to-right. ( but not completely clear ).

So I tried this one

var a = 5, b = 3; 
a = ( ( b = ( a = a+b ) - b ) - a );

Now I got a = -3 and b = 5. Can somebody explain me why this is happening like this ?

5 Answers 5

2

Here is the explanation, I hope it is clear because it is not so obvious. JS and all other languages create a tree to evaluate expressions. The tree assigns a weight to each operator depending on their position and on the braces.

First, here is the steps JS would process the expression:

Step 0. a = ( a - ( b = ( a = a+b ) - b ) );   a=5, b=3
Step 1.                   a = a+b              a=8, b=3
Step 2.             b = a - b                  a=8, b=5 
Step 3. a = a - b                              a=0, b=5

At each step it processes one operator.

And this is the tree it creates from you expression:

    =
  /   \
 a     - 
     /    \
   a       =
          /  \   
         b    -            
             / \
            =   b
           /  \
          a    +
              / \
             a   b

The tree is then processed from bottom to top.

Sign up to request clarification or add additional context in comments.

6 Comments

But , in the third step a = a-b should give me result as a=3 and b=5. isn't it ? Because step2 changed the value of a and b as a = 8 and b =3. I'm bit confused
Look at my answer: stackoverflow.com/a/19045816/1324929. What @KLiFF fails to mention is that with assignment, the first step is expression evaluation on the right side. Thus, a = ( a -( b = ( a = a+b ) - b ) ) becomes a = ( 5 -( b = ( a = 5+3 ) - 3 ) ). After that, the right side, from inner parens to outer parens, a = 5+3, a becomes 8, b = 8-3, b becomes 5 and finally a = 5-5, a becomes 0, b remains 5.
not exactly. The tree is processed from left to right, otherwise a = 8 in your first left node.
It is indeed very confusing, but here is the explanation: The a from the left was already evaluated and has a value of 5, the a from the right is is the result of the calculations from the right branch of the tree and has a value of 8. So there is in fact an a and an a'.
How the tree is processed exactly ? Is it from bottom to top OR left to right ? I read that arithmetic expressions are evaluated from left to right. If I apply the same logic here, then it makes sense .. It produces the correct ouput .. Only one more clarification I need is when processing the left node, it should be processing all of it's child nodes before moving to the right node .. isn't it ?
|
1

As you said, the expression is evaluated from left to right, meaning the first time a is encountered, its value is still 5. This comes down to:

var a = 5, b = 3; 
a = ( a -( b = ( a = a+b ) - b ) );
a = 5 - (b = (a=(5+3)) - b);
a = 5 - (b = 8 - b);
a = 5 - 5; AND b = 5

In the second one, the a value is evaluated after the assignment because it is on the right

var a = 5, b = 3;
a = ( ( b = ( a = a+b ) - b ) - a );
a = ( ( b = 8 - b ) - a ); AND a = 8
a = ( 5 - 8 ); AND a = 8; AND b = 5;
a = - 3;

It all comes down to the order of the evaluation of the operands.

Typically in the first case, a is evaluated to 5, then b = ( a = a+b ) - b is evaluated, and only during this evaluation the value of a changes, but is not backported.

In the second example, ( b = ( a = a+b ) - b ) is evaluated first, changing the a value to 8, then a is evaluated, and is found to be 8

A more trivial example is :

var a = 5
a = a + (a = 2)
// a = 7

a is evaluated to 5, then (a = 2) is evaluated to 2 and a is set to 2, then 5+2 is evaluated and a is set to 7.

On the other hand :

var a = 5
a = (a = 2) + a
// a = 4

(a = 2) is evaluated to 2 and a is set to 2, then a is evaluated to 2, then 2+2 is evaluated and a is set to 4

Comments

1
var a = 5, b = 3;
a = ( ( b = ( a = a+b ) - b ) - a );

It will operate in this way.

a = a + b //8
b = a - b //8-3=5
a = b - a //5-8=-3

2 Comments

Why did the a = ( a -( b = ( a = a+b ) - b ) ); gave me a=0 and b=5
Yes, my best guess is a is set to 5 before the expression (a = a+b), so a stays 5.
0
var a = 5, b = 3; 
a = ( a -( b = ( a = a+b ) - b ) );

1) a = a(5) - (rest of expression, where 2 parts will be calculated soon)

2) b = (a = a+b // and it's still not calculated) - b (which is 3, because new b is not changed yet)

3) a = 5(a) + 3(b) = 8

4) b(we are back to point 2) = 8(new a) - 3(old b) = 5

5) a(point 1) = 5(old a) - 5(new b) = 0

New a = 0, new b = 5

var a = 5, b = 3; 
a = ( ( b = ( a = a+b ) - b ) - a );

1) b = ( a = a+b ) - 3(b)

2) a = 5(a) + 3(b) = 8

3) b = 8(new a) - 3(old b) = 5

4) a(final) = 5(new b) - 8(new a) = -3

New a = -3, new b = 5

I hope it's readable :D

Comments

0
a = ( a -( b = ( a = a+b ) - b ) ) 

is similar to this

a = ( 5 -( b = ( a = 5+3 ) - 3 ) ) // a = 8
// a = ( 5 - ( b = 8 - 3 ) ) // b = 5
// a = ( 5 - 5 ) // a = 0

meaning it will replace a and b on the left side of = in one go with the same initial values, it's not similar to this sequence

a = a+b; // a = 8
b = a-b; // b = 5
a = a-b; // a = 3

as you expect.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.