JavaScript 中的 POSTFIX 和 PREFIX increment/decrement 优先级

POSTFIX and PREFIX increment/decrement precedence in JavaScript

我已经编码多年,突然坚持了一些关于 increment/decrement 运算符的运算符优先级的简单事情。

根据https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence postfix increment/decrement 比 prefix 具有更高的优先级。 所以,我希望在表达式

x = --a  + a++;  

首先计算增量,然后才计算减量。 但是,在测试中,这个表达式从左到右计算,就像运算符具有相同的优先级一样。结果 a=1;x = --a + a++ 等于 0 而不是 2。

好的。假设 prefix/postfix 运算符具有相同的优先级,我尝试用括号重新排序:

a=1;x = --a  + ( a++ )

但同样,结果将是 0 而不是我预期的 2。

有人可以解释一下吗?为什么这里的括号不影响任何东西?我怎样才能看到后缀的优先级高于前缀?

在表达式中,求值过程如下:

  1. --a 被评估。变量a递减,因此--a的值是0.
  2. a++ 被评估。得到a的值,然后然后a递增。因此 a++ 的值是 0.
  3. 执行+运算,结果为0
  4. a的最终值为1

因为 --aa++ 位于优先级较低的 + 运算符的任一侧,因此预递减和 post-递增之间的优先级差异不没关系; + 运算符先计算左侧子表达式,然后再计算右侧子表达式。

嗯,这很奇怪,但看起来 increment/decrement 在表达式中的行为类似于函数调用,而不像运算符。 我找不到任何关于表达式中函数求值顺序的文档,但看起来它忽略了任何优先规则。这么奇怪的表情:

console.log(1) +  console.log(2)* ( console.log(3)  + console.log(4))

将在控制台中显示 1234。我能找到的唯一解释为什么括号不影响表达式

中 dec/inc 的求值顺序

运算符优先级与求值顺序不同。

运算符优先级告诉你

f() + g() * h()

被解析为

f() + (g() * h())

(因为*的优先级高于+),但不是先调用哪个函数。这是由评估顺序控制的,在 JavaScript 中总是从左到右。

括号仅覆盖优先级(即它们影响子表达式的分组方式),而不影响计算顺序:

(f() + g()) * h()

在乘法之前执行加法,但在所有情况下 f 首先调用,h 最后调用。

在你的例子中

--a + a++

前缀 -- 和后缀 ++ 的相对优先级无关紧要,因为它们不属于同一个操作数。中缀 + 的优先级低得多,所以这个表达式解析为

(--a) + (a++)

一如既往,JS 表达式是从左到右求值的,所以 --a 先求值。

如果你写了

--a++

会被解析为

--(a++)

(而不是 (--a)++),因为后缀 ++ 具有更高的优先级,但这里的区别并不重要,因为任何一个版本都是错误的:你不能 increment/decrement另一个 increment/decrement 操作的结果。

但是,在 operator precedence table 中,您可以看到所有前缀运算符都具有相同的优先级,因此我们可以显示一个替代方案:

// ! has the same precedence as prefix ++
!a++

是有效代码,因为它解析为 !(a++),因为后缀 ++ 的优先级高于 !。如果没有,它将被解释为 (!a)++,这是一个错误。