Ответ 1
Это преднамеренная часть языка и описывается в Спецификация ECMAScript Language. Синтаксис для оператора запятой определяется в Раздел 12.16, в котором говорится следующее:
12.16 Comma Operator (,)
Синтаксис
Expression: AssignmentExpression Expression, AssignmentExpression
Здесь спецификация описывает, как используется оператор запятой. Expression
- это любой AssignmentExpression
или сам по себе с запятой (оператор) и другой AssignmentExpression
. Важно отметить, что AssignmentExpression
- это Expression
, но Expression
не a AssignmentExpression
.
Что касается фактического условного оператора, то грамматика для оператора и условных выражений определяется в Раздел 12.14:
12.14 Условный оператор (?:)
Синтаксис
ConditionalExpression: LogicalORExpression LogicalORExpression ? AssignmentExpression : AssignmentExpression
По спецификации условное выражение может содержать только AssignmentExpression
s - не только Expression
s. Таким образом, условный оператор не может иметь запятый оператор внутри одного из своих операндов. Это может показаться странным причудом языка, но есть определенная причина, учитывающая очень специфическую грамматику и спецификацию:
ПРИМЕЧАНИЕ Грамматика для
ConditionalExpression
в ECMAScript несколько отличается от грамматики в C и Java, каждая из которых позволяет второму подвыражению бытьExpression
1 но ограничиваем третье выражениеConditionalExpression
. Мотивация для этой разницы в ECMAScript заключается в том, чтобы позволить выражению присваивания управляться любым выражением условного и , чтобы устранить запутанный и довольно бесполезный случай выражения запятой в качестве центрального выражения.
Из-за строгой грамматики Java и C они не допускают таких вещей (Java):
int a = 2;
int b = 1;
System.out.println(a > b ? b = a : a = b); //Can't use assignment in 'else' part
// ^^^^^
Авторы ECMAScript решили разрешить назначение в обеих ветвях тернарного оператора, таким образом, это определение с AssignmentExpression
произошло. Следовательно, это определение также запрещает, чтобы оператор-запятая фактически отображался в "if" части условного оператора, но из-за его скудности и бесполезности это не было проблемой. Они по сути убили двух зайцев одним камнем; допускал более мягкую грамматику и избавлялся от бесполезного синтаксиса, что плохой практикой.
Причина, по которой добавление оператора группировки позволяет ему работать, заключается в том, что производство оператора группировки ( Expression )
по определению также означает AssignmentExpression
, позволяющее ему находиться в тройном операторе, см. str answer для более подробной информации.
1 Это относится к Java Expression
, а не к ECMAScript Expression
. Java не имеет оператор запятой, поэтому его Expression
не включает.