JavaScript运算符优先算法



我有一个例子:

let x = 4
console.log(x++ + ++x + x--)

它返回16,但我不明白怎么回事。如果我们在MDN中查找,会发现一个运算符优先级表。所以有这样一个优先级:

  1. Postfix增量
  2. Postfix递减
  3. 前缀增量
  4. 添加

使用此逻辑,它应该返回14

  1. x++=4-(5(->记住下一个呼叫
  2. x--=5-(4(->记住下一个呼叫
  3. ++x=5
  4. +

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

最新更新