Search code examples
javascriptoperatorsshorthandchained

Why are these chained shorthand operators not working?


While writing a swap function using chained shorthand operators in javascript, I stumbled upon something which puzzled me a lot.

This code is supposed to swap a and b values.

var a = 4532;
var b = 969;

a^=b^=a^=b;

But it doesn't: b = 4532, but a = 0.

If I break this code in 2 lines, it works as intended.

var a = 4532;
var b = 969;

b^=a^=b;
a^=b;

What is the technical explanation?

PS: here's the code on jsfiddle if someone wants to quickly try for himself.


Solution

  • Before answering your question, can you tell the result of the following code?

    var c = 1;
    c += c += 1;
    

    You may believe that it's 4, try it yourself :)

    I have no idea of how the javascript code is interpreted under the hood. Here is how I try to explain why that happened.

    By a += b, it is equal to a = a + b. So, c += c += 1 is c = c + (c = c + 1). Assignment in form of (c + (c = c + 1)), the result is (c + c + 1). Here I think it is the key point, and it's confusing, the variable c is still 1, although we reassign a new value c + 1 to it, in the first assignment c += 1.

    So, a^=b^=a^=b is equal to a = a^b^a^b, that's 0. Because the internal change to a is ignored, or maybe it's a bug?

    My another guess is that, the code may be expanded like this:

    c = 1 + (c = 1 + 1)// in form of c = c + (c = c + 1)
    

    That's all my guesses, cause I don't know how the bytecode generated by VM looks like. Hopes it is useful.