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。
有人可以解释一下吗?为什么这里的括号不影响任何东西?我怎样才能看到后缀的优先级高于前缀?
在表达式中,求值过程如下:
--a
被评估。变量a
递减,因此--a
的值是0
.
a++
被评估。得到a
的值,然后然后a
递增。因此 a++
的值是 0
.
- 执行
+
运算,结果为0
。
a
的最终值为1
。
因为 --a
和 a++
位于优先级较低的 +
运算符的任一侧,因此预递减和 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)++
,这是一个错误。
我已经编码多年,突然坚持了一些关于 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。
有人可以解释一下吗?为什么这里的括号不影响任何东西?我怎样才能看到后缀的优先级高于前缀?
在表达式中,求值过程如下:
--a
被评估。变量a
递减,因此--a
的值是0
.a++
被评估。得到a
的值,然后然后a
递增。因此a++
的值是0
.- 执行
+
运算,结果为0
。 a
的最终值为1
。
因为 --a
和 a++
位于优先级较低的 +
运算符的任一侧,因此预递减和 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)++
,这是一个错误。