Search code examples
javascriptparentheses

How are parentheses (round brackets) evaluated in javascript (ES5/6)


Consider the following case, which can (as an example) be used to perform one-line swaps:

let a = (10,20)
console.log(a)
> 20

An example performing a swap

let a = 1, b = 2
a = b + (b=a, 0)
console.log(a, b)
>2,1

I'm used to seeing parentheses wrapping function declarations creating self invoking functions, but I'm not sure what's happening in the above case. How is (10,20) or (b=a, 0) being treated by javascript? Is it a function returning the final value, or a data type which when accessed will always give the last item, or something else?


To clarify, I am not looking for tips on how to perform a swap, but an explanation of the above syntax.


Solution

  • The key here isn't so much the parentheses, which are just there for grouping, it's the comma operator. The comma operator evaluates its operands, left to right, throwing away the result values other than the final operand's value, which becomes the result.

    So that swap operation works like this:

    1. Evaluate the right-hand side of the assignment, b + (b=a, 0)

      1. Get the current value of b (say, 2)

      2. Evaluate (b=a, 0)

        1. Evaluate b=a, assigning the current value of a (1) to b
        2. Throw away the result of that assignment (but keep the side effect)
        3. Evaluate 0 and take that as the result of the comma expression
      3. So now it's 2 + 0 which is 2

    2. Assign that value to a

    So that succeeds in swapping a and b by copying a's original value to b in Step 1.2.1, and copying b's original value to a in Step 1.1 (getting the value before changing b) and Step 2 (putting that value in a).


    Side note: The modern (ES2015+) way to do a swap is to use destructuring notation:

    ([a, b] = [b, a]);
    

    Live Example:

    let a= 1, b = 2;
    ([a, b] = [b, a]);
    console.log("a", a);
    console.log("b", b);