考虑一个可由下面的表示描述的表达式,其中操作1
和OP2(操作2)
是用于OPerator的填充板。
a OP1 b OP2 c
上述组合有两种可能的解释:
(a OP1 b)OP2 ca OP1(b OP2 c)
语言决定采用哪一种取决于操作1
和OP2(操作2)
.
如果操作1
和OP2(操作2)
具有不同的优先级(见下表),运算符的优先级较高优先首先,关联性并不重要。观察乘法如何比加法具有更高的优先级,并首先执行,即使加法是在代码中首先写入的。
控制台.log(3+10*2);//23控制台.log(3+(10*2));//23,因为这里的括号是多余的控制台.log((3+10)*2);//26,因为括号改变了顺序
在具有相同优先级的运算符中,语言按以下方式对其进行分组结合性.左旋社交(从左到右)表示它被解释为(a OP1 b)OP2 c
,同时权利社会性(从右到左)表示它被解释为a OP1(b OP2 c)
。赋值运算符是右关联的,因此您可以编写:
预期结果是一
和b
得到值5。这是因为赋值运算符返回所赋值。第一,b
设置为5。然后一
也设置为5-的返回值b=5
,也称为赋值的右操作数。
另一个例子是,唯一指数运算符具有右关联性,而其他算术运算符具有左关联性。
常数a=4**3**2;//同4**(3**2);评估为262144常数b=4/3/2;//与(4/3)/2相同;评估值为0.6666。。。
操作符首先按优先级分组,然后,对于具有相同优先级的相邻操作符,则按关联性分组。所以,当混合除法和求幂时,求幂总是在除法之前。例如,2 ** 3 / 3 ** 2
结果为0.88888888888,因为它与(2 ** 3) / (3 ** 2)
.
对于前缀一元运算符,假设我们有以下模式:
OP1和OP2 b
哪里操作1
是前缀一元运算符,并且OP2(操作2)
是二进制运算符。如果操作1
优先级高于OP2(操作2)
,则将其分组为(OP1 a)OP2 b
; 否则,就会OP1(一个OP2 b)
.
常数a=1;常数b=2;a+b类型;//相当于(a型)+b;结果是“数字2”
如果一元运算符位于第二个操作数上:
a OP2 OP1 b
然后是二进制运算符OP2(操作2)
必须具有低于一元运算符的优先级操作1
将其分组为a OP2(OP1b)
。例如,以下内容无效:
因为+
优先级高于产量
,这将成为(a+产量)1
-但是因为产量
是一个保留字在生成器函数中,这将是一个语法错误。幸运的是,大多数一元运算符的优先级都高于二进制运算符,因此不会受到此缺陷的影响。
如果我们有两个前缀一元运算符:
OP1 OP2一个
然后一元运算符更接近操作数,OP2(操作2)
的优先级必须高于操作1
将其分组为OP1(OP2 a)
。有可能以另一种方式得到它,最终(OP1 OP2)a
:
因为等待
优先级高于产量
,这将成为(等待产量)1
,它正在等待名为产量
和语法错误。同样,如果你有新的!A;
,因为!
优先级低于新的
,这将成为(新!)A
,这显然是无效的。(无论如何,写这段代码看起来毫无意义,因为!A类
总是生成布尔值,而不是构造函数。)
对于后缀一元运算符(即,++
和--
),同样的规则也适用。幸运的是,这两个操作符的优先级都高于任何二进制操作符,因此分组始终是您所期望的。此外,因为++
计算为价值,不是参考,也不能像在C语言中那样将多个增量链接在一起。
设a=1;a++++;//语法错误:后缀操作中的左侧无效。
将处理操作员优先级递归地。例如,考虑以下表达式:
首先,我们通过降低优先级来对不同优先级的操作符进行分组。
- 这个
**
运算符具有最高优先级,因此它首先分组。
- 环顾四周
**
表情,它有*
在右边和+
在左边。*
具有更高的优先级,因此首先对其进行分组。*
和/
具有相同的优先级,所以我们暂时将它们分组。
- 环顾四周
*
//
表达式分组为2,因为+
优先级高于>>
,前者被分组。
(1 + ( (2 ** 3) * 4 / 5) ) >> 6// │ │ └─ 1. ─┘ │ │// │ └────── 2───────┘ │// └────────── 三。──────────┘
在*
//
组,因为它们都是左关联的,所以左操作数将被分组。
(1 + ( ( (2 ** 3) * 4 ) / 5) ) >> 6// │ │ │ └─ 1─┘ │ │ │// │ └─│─────── 2───│────┘ │// └──────│───── 三。─────│──────┘// └───── 4. ─────┘
请注意,运算符优先级和关联性仅影响操作员(隐式分组),但不是操作数。操作数总是从左到右进行计算。通常首先计算高阶概率表达式,然后根据运算符优先级的顺序组合其结果。
函数echo(name,num){console.log(`评估${name}端`);返回num;}//指数运算符(**)是右关联的,//但是具有更高优先级的所有调用表达式(echo()),//将在**之前进行评估控制台.log(echo(“左”,4)**echo;//评估左侧//评估中间面//评估右侧// 262144//指数运算符(**)的优先级高于除法运算符(/),//但求值总是从左操作数开始控制台.log(echo(“左”,4)/echo(“中”,3)**echo,(“右”,2));//评估左侧//评估中间面//评估右侧// 0.4444444444444444
如果您熟悉二叉树,请将其视为后序遍历.
/┌────────┴────────┐echo(“左”,4)**┌────────┴────────┐echo(“中间”,3)echo
在所有操作符都正确分组后,二进制操作符将形成一个二叉树。评估从最外层的组开始,该组是优先级最低的运算符(/
在这种情况下)。首先计算此运算符的左操作数,它可以由更高优先级的运算符(例如调用表达式)组成echo(“左”,4)
). 左操作数求值后,右操作数以相同的方式求值。因此,所有叶节点-echo()
调用-将从左到右访问,而不管加入它们的操作员的优先级如何。