为什么JavaScript UpdateExpression语法如此定义?
根据Ecma-262,前缀递增和递减运算符定义为:为什么JavaScript UpdateExpression语法如此定义?,javascript,syntax,language-design,Javascript,Syntax,Language Design,根据Ecma-262,前缀递增和递减运算符定义为: UpdateExpression : LeftHandSideExpression ++ LeftHandSideExpression ‐‐ ++ UnaryExpression ‐‐ UnaryExpression 这是令人惊讶的,后缀和前缀运算符都是在同一规则中定义的,而且它是++UnaryExpression,而通常一元表达式肯定不是update运算符的有效参数 在UnaryExpression本身中定义
UpdateExpression :
LeftHandSideExpression ++
LeftHandSideExpression ‐‐
++ UnaryExpression
‐‐ UnaryExpression
这是令人惊讶的,后缀和前缀运算符都是在同一规则中定义的,而且它是++UnaryExpression
,而通常一元表达式肯定不是update运算符的有效参数
在UnaryExpression
本身中定义前缀递增运算符和递减运算符,以及其他前缀运算符,似乎更简洁、更符合逻辑,其他C语法语言也会这样做,例如,C标准第6.5.3节定义了一元表达式
,包括前缀更新运算符和其他运算符
为什么JavaScript会这样定义这些操作符
为什么JavaScript会这样定义这些操作符
它主要是历史性的,就像规范中的许多其他奇怪之处一样
在UnaryExpression
本身中定义前缀递增运算符和递减运算符,以及其他前缀运算符,似乎更简洁、更符合逻辑,其他C语法语言也会这样做
事实上,这就是它多年来的定义,在和。它很简单,每个优先级别都有一个语法结果(PostfixExpression
是下一个更紧的语法结果),并且可能是在构思JS时直接从C或Java语法继承的
当然,一元表达式通常不是更新运算符的有效参数
在C语言中,--x
实际上是有效的,因此前缀递增和递减运算符表达式包含另一个一元表达式。当然,它在尝试计算表达式时会抛出异常,但在ES5中解析它可以正常工作
ES6随后添加了早期错误的概念,以及现在解析时的递增和递减操作。然而,这并没有被编码在句法作品中
令人惊讶的是,后缀和前缀运算符是在同一条规则中定义的
这个定义是正确的。它随着引入求幂运算符而改变,其中PostfixExpression
被重命名为UpdateExpression
,前缀运算符被移动到规则中。像这样的一些更改是必要的,因为**
操作符允许使用更新表达式,但不允许使用一元表达式作为其第一个参数(因为一元减号,如-x**3
中的一元减号,被认为太模糊)。我不能开始声称完全理解规范中对语法结果所做的决定,因此,我(或您!)可能会很高兴发布一个答案,但我可以为您观察到两件事:规范经常以这种方式将相关语法表达式分组在一起,并且单独处理了并非所有非AryExpressions都是有效目标的问题。@melpomene是吗?如果++被指定接受一个调用表达式,那么可能是这样的,但由于某种原因,它实际上被指定接受一元表达式,而一元表达式又可以是另一个更新表达式,除非我遗漏了什么?在ES6中,它们是在UnaryExpression
:…中定义的,这让我想知道区别是什么。ES8将wait
作为一元表达式,但肯定不会返回引用吗?@Bergi就是这样。我是从2017年的版本开始工作的,这意味着它们以前是以直观的方式定义的,然后改为非直观的方式。这就更奇怪了。