我有一个例子:
let x = 4
console.log(x++ + ++x + x--)
它返回16
,但我不明白怎么回事。如果我们在MDN中查找,会发现一个运算符优先级表。所以有这样一个优先级:
- Postfix增量
- Postfix递减
- 前缀增量
- 添加
使用此逻辑,它应该返回14
x++
=4-(5(->记住下一个呼叫x--
=5-(4(->记住下一个呼叫++x
=5+
4 + 5 + 5 = 14
有人能解释一下,运算符解析器算法是如何与一元运算符和二元运算符一起工作的吗?
应用运算符优先级后,分组看起来像:
((x++) + (++x)) + (x--)
解释器将从左到右计算两个+
,并在遇到它们时解析内部表达式增量/递减不会立即运行,也不会在+
s之前运行-它们只在解释器确定需要计算其表达式时运行。这就是发生的事情,按顺序:
x is 4
((x++) + (++x)) + (x--)
evaluate postfix increment: insert 4, x increases to 5
(4 + (++x)) + (x--)
evaluate prefix increment: x increases to 6, insert 6
(4 + 6) + (x--)
simplify:
10 + (x--)
evaluate postfix decrement: insert 6, x decreases to 5
10 + 6
最终值为16。
顺序完全一致。您正在从左到右计算并应用优先级。我将按步骤分解:
1.增量后x++
//x = 4
x++ + ++x + x--
^^^
|
--> expression = 4
--> x = 5
首先对CCD_ 11进行了评价。Postfix增量的优先级高于加法,因此我们必须首先解决它。该表达式产生4
(当时x
的值(,但是,x
的值也会随着将来的读取而递增。
2.预增++x
//x = 5
4 + ++x + x--
^^^
|
--> x = 6
--> expression = 5
接下来计算++x
,因为前缀增量也比加法具有更高的优先级,所以我们必须在表达式a + b
之前解析它。我们还不关心x--
,因为我们还没有开始。
因此,前缀增量将使x
的值从5
增加到6
,然后返回该新值。
3.添加(x++) + (++x)
//x = 6
4 + 6 + x--
^^^^^
|
--> expression = 10
我们已经解决了优先级较高的表达式,所以是时候添加了。即简单的CCD_ 23。
4.减量后x--
//x = 6
10 + x--
^^^
|
--> expression = 6
--> x = 5
我们到达了另一个a + b
构造,但后缀递减x--
的优先级更高,所以我们首先解决这个问题。x
的当前值为6
,我们返回该值,然后将x
递减到5
。
5.添加((x++) + (++x)) + (x--)
//x = 5
10 + 6
^^^^^^
|
--> expression = 16
最后,在解决了具有更高优先级的所有内容之后的另一个简单加法:10 + 6 = 16
您可以使用一个值表,一个用于x
,其中包含实际值/post值或pre值和实际值。
然后根据反方的顺序取值,并将这些值相加。
let x = 4
console.log(x++ + ++x + x--); // 16
post pre post increment
x 4 5 5 6 6 5 different values
value 4 6 6 values for addition
let x = 4
console.log(x++ + ++x + x--); // 16