Search code examples
javacgrammarecmascript-5conditional-operator

Grammar difference of ConditionalExpression between ECMAScript and C/Java


Quote from the ECMAScript Language Specification

The grammar for a ConditionalExpression in ECMAScript is a little bit different from that in C and Java, which each allow the second subexpression to be an Expression but restrict the third expression to be a ConditionalExpression. The motivation for this difference in ECMAScript is to allow an assignment expression to be governed by either arm of a conditional and to eliminate the confusing and fairly useless case of a comma expression as the centre expression.

Can someone please explain the difference in more detail using examples? What is meant by useless case of a comma expression as the centre expression? Why does a conditional expression in C/Java not allow an assignment expression to be governed by either arm of a conditional?


Solution

  • In JavaScript, you can do this:

    foo(condition ? a = 1 : b = 2);
    

    (Whether you should is another thing, but you can.)

    ...and the result will be that the condition is evaluated, and either a gets assigned 1 or b gets assigned 2, and then foo is called with either 1 or 2.

    You can't do that in Java (I can't speak to C, it's been ~25 years), because it doesn't allow you to put an assignment expression in the third operand. Bizarrely, it does allow you to put an assignment expression in the second operand, so you can do this:

    foo(condition ? a = 1 : 2);
    

    ...even in Java.

    Returning to JavaScript: If you weren't allowed to do

    foo(condition ? a = 1 : b = 2);
    

    ...for the same reason as Java, you could work around it by doing this:

    foo(condition ? a = 1 : (b = 2, b));
    // ---------------------^-----^^^^
    

    ...because JavaScript has the comma operator which evaluates its operands and then takes the result of the right-hand operand as its value. A comma expression (b = 2, b) isn't an assignment expression, so it would work around a restiction disallowing an assignment expression in the conditional operators's third operand (even though one of the expressions feeding into the comma expression, b = 2, is an assignment expression).

    So by allowing assignment expression even in the third operand, JavaScript avoids the pointless use of a comma expression there.