Search code examples
javascriptoperator-precedenceexponentecmascript-2016

Why is there a syntax error when the left operand of the exponentiation operator is negative?


When I use the exponent operator (**) in JavaScript, it normally works as expected:

2 ** 2   // 4
2 ** -2  // 0.25

But when the left operand is negative

-2 ** 2

I get a syntax error:

Uncaught SyntaxError: Unexpected token **

I can get around it easily by putting parentheses around -2

(-2) ** 2 // 4

but I'm curious about what caused this error. Other operators (+ - * / % etc) don't have this problem. Why does this happen for the ** operator?


Solution

  • This behavior is intentional and is there to prevent you from writing ambiguous expressions. From MDN:

    In most languages like PHP and Python and others that have an exponentiation operator (**), the exponentiation operator is defined to have a higher precedence than unary operators such as unary + and unary -, but there are a few exceptions. For example, in Bash the ** operator is defined to have a lower precedence than unary operators. In JavaScript, it is impossible to write an ambiguous exponentiation expression, i.e. you cannot put a unary operator (+/-/~/!/delete/void/typeof) immediately before the base number.

    -2 ** 2; 
    // 4 in Bash, -4 in other languages. 
    // This is invalid in JavaScript, as the operation is ambiguous. 
    
    
    -(2 ** 2); 
    // -4 in JavaScript and the author's intention is unambiguous.