这是语言中有意的一部分,并在ECMAScript Language Specification中进行了概述。逗号运算符的语法在Section 12.16中定义,其中规定如下:
12.16 Comma Operator ( , )
语法
表达式:
赋值表达式
表达式,赋值表达式
在这里,规范概述了逗号运算符的使用方式。一个Expression
是任何AssignmentExpression
或者是它本身后跟一个逗号(该运算符)和另一个AssignmentExpression
。需要注意的重要事项是,AssignmentExpression
是一个Expression
,但是Expression
不是一个AssignmentExpression
。
至于实际的条件运算符,操作符和条件表达式的语法在Section 12.14中指定:
12.14 条件运算符 ( ? : )
语法
ConditionalExpression:
LogicalORExpression
LogicalORExpression ? AssignmentExpression : AssignmentExpression
根据规范,条件表达式只能包含AssignmentExpression
,而不仅仅是Expression
。因此,条件运算符不能在其操作数中的一个操作数内部有逗号运算符。这似乎是语言的一个奇怪的怪癖,但考虑到非常特定的语法,规范有一个具体的原因:
注意:在ECMAScript中,
ConditionalExpression
的语法与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's answer以获取更多详细信息。
1 这里指的是Java的Expression
,而不是ECMAScript的Expression
。Java没有逗号运算符,因此它的Expression
不包括它。
ecmascript-6
标签,尽管我认为它适用的唯一原因是您不必要地使用const
关键字而不是var
。 - Dexygen