I noticed something odd when trying to use the comma operator inside the conditional (ternary) operator for logging. Here's a contrived example:
const a = 2; const b = 1; a > b ? console.log(a), a : b; //I expect this to log and evaluate to a
But instead I'm met with this:
Uncaught SyntaxError: Unexpected token ,
According to the MDN documentation, the conditional operator accepts two expressions as the 'if' and 'else' cases of the ternary operator, and the comma operator theoretically is an expression as,
The comma operator evaluates each of its operands (from left to right) and returns the value of the last operand.
So why do I get a syntax error? The comma operator is an expression which should be allowed to be in a conditional operator. Although, putting parentheses around the comma's operands works fine:
a > b ? (console.log(a), a) : b; //Logs and gives a
Why does that work fine? Parentheses (or the grouping operator) allows the interpreter to know it's dealing with an expression, but console.log(a), a
is already an expression without the need of parentheses, so why do I get a syntax error without them?
The conditional (ternary) operator is the only JavaScript operator that takes three operands: a condition followed by a question mark ( ? ), then an expression to execute if the condition is truthy followed by a colon ( : ), and finally the expression to execute if the condition is falsy.
The comma operator ( , ) evaluates each of its operands (from left to right) and returns the value of the last operand. This lets you create a compound expression in which multiple expressions are evaluated, with the compound expression's final value being the value of the rightmost of its member expressions.
No, it's absolutely not allowed. throw is a statement and it can't be part of an expression.
A ternary operator is a three-operand operator that is supported in most programming languages, including JavaScript, Java, C++, C#, and many others. It is also referred to as a conditional operator because it is considered to be a more concise alternative to the conditional ( if-else ) statement.
This is an intentional part of the language, and is outlined in the ECMAScript Language Specification. The syntax for the comma operator is defined in Section 12.16, which states the following:
12.16 Comma Operator ( , )
Syntax
Expression: AssignmentExpression Expression, AssignmentExpression
Here, the specification outlines how the comma operator is used. An Expression
is any AssignmentExpression
or itself followed with a comma (the operator) and another AssignmentExpression
. The important thing to note is that an AssignmentExpression
is an Expression
but an Expression
is not an AssignmentExpression
.
As for the actual conditional operator, the grammar for the operator and conditional expressions is specificed in Section 12.14:
12.14 Conditional Operator ( ? : )
Syntax
ConditionalExpression: LogicalORExpression LogicalORExpression ? AssignmentExpression : AssignmentExpression
By the specification, a conditional expression can only contain AssignmentExpression
s -- not just Expression
s. Thus a conditional operator cannot have a comma operator inside one of its operands. This may seem like a weird quirk of language, but there is a specific reason considering the very specific grammar, and per the specification:
NOTE The grammar for a
ConditionalExpression
in ECMAScript is slightly different from that in C and Java, which each allow the second subexpression to be anExpression
1 but restrict the third expression to be aConditionalExpression
. 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.
Because of Java and C's restrictive grammar, they do not allow things like this (Java):
int a = 2; int b = 1; System.out.println(a > b ? b = a : a = b); //Can't use assignment in 'else' part // ^^^^^
ECMAScript authors decided to allow for assignment in both branches of the ternary operator, thus this definition with AssignmentExpression
occurred. Consequently, this definition also disallows for the comma operator to actually show up in the 'if' part of the conditional operator, but because of its scarcity and uselessness it wasn't a problem. They essentially killed two birds with one stone; allowed for more lenient grammar and got rid of useless syntax that's bad practice.
The reason why adding the grouping operator allows it to work is because the grouping operator production ( Expression )
is by definition also an AssignmentExpression
allowing it to be in the ternary operator, see str's answer for more details.
1 This refers to Java's Expression
, not ECMAScript's Expression
. Java's does not have the comma operator so its Expression
does not include it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With