Javascript 简明教程
JavaScript - Operator Precedence
在 Javascript 中, operator precedence 确保了在单个表达式包含多个运算符时,执行运算符的优先级。因此,无论哪个表达式具有较高的优先级,编译器都会先对它执行其他运算符,然后执行具有较低优先级的运算符。
每当你使用只有 1 或 2 个操作符编写任何 Javascript 表达式时,就可以轻松理解该表达式的输出。但是当表达式包含多个运算符时,你应该了解运算符优先级概念才能正确评估表达式。
运算符优先级最好的例子是,在传统数学中,乘法运算符的优先级高于加法或减法运算符。因此,如果任何数学表达式同时包含乘法和加法运算符,则需要首先执行乘法。
Associativity
关联性这一术语是指编译器在求解表达式时应该遵循的方向。在许多情况下,运算符有相同的优先级。在这种情况中,编译器应该先执行哪一个操作会出现歧义。因此,编译器会借助关联性。它可以从左到右,也可以从右到左。
例如,我们需要执行以下表达式。
let res = 50/5*2;
-
将上述表达式看作 (50 / 5) * 2 得出 20 作为输出。
-
像 50 / (5 * 2) 这样评估表达式得出的结果值为 5。
为了解决上述歧义,编译器使用关联性规则。除法和乘法运算符的关联性是从左到右。因此,它将表达式求值为 (50 / 5) * 2。
赋值运算符具有从右到左的关联性。考虑以下赋值表达式。
P = q = 90;
在上述表达式中,90 赋值给 q,q 变量的值赋值给 p。
简而言之,JavaScript 编译器根据运算符优先级求解表达式,当多个运算符具有相同的优先级时,它会使用关联性规则。
Operator Precedence Table
下表包含运算符、其描述、关联性方向和一个简短示例。
Operator Precedence |
Operator |
Description |
Associativity |
Example |
1 |
() |
Grouping |
L → R |
(expression) |
2 |
. |
Member of object |
L → R |
Object_name.property |
2 |
() |
Function call |
L → R |
Demo() |
2 |
new |
To create objects |
R → L |
New test() |
2 |
[] |
Member of object |
L → R |
Object["property"] |
3 |
— |
Postfix decrement |
- |
p--; |
3 |
++ |
Postfix increment |
- |
p++ |
4 |
— |
Prefix decrement |
R → L |
--p; |
4 |
++ |
Prefix increment |
R → L |
++p; |
4 |
typeof |
要获取变量类型 |
R → L |
typeof a; |
4 |
! |
Logical not |
R → L |
!a; |
4 |
~ |
Bitwise not |
R → L |
~p |
4 |
- |
Unary minus |
R → L |
-p |
4 |
+ |
Unary plus |
R → L |
+p |
4 |
delete |
To delete object property |
R → L |
Delete arr[0] |
4 |
void |
Evaluates void |
R → L |
Void(1) |
5 |
** |
Exponentiation operator |
R → L |
p ** q |
6 |
* |
Multiplication |
L → R |
p * q |
6 |
/ |
Division |
L → R |
p / q |
6 |
% |
modulo |
L → R |
p % q |
7 |
+ |
Addition or plus operator |
L → R |
p + q |
7 |
- |
Subtraction operator |
L → R |
p - q |
8 |
<< |
Left shift |
L → R |
p << 2 |
8 |
>> |
Signed right shift |
L → R |
p >> 2 |
8 |
>>> |
Unsigned right shift |
L → R |
p >>> 2 |
9 |
in |
Property in object |
L → R |
x in y |
9 |
instanceof |
Instance of object |
L → R |
p instanceof Object |
9 |
< |
Less than |
L → R |
p < q |
9 |
⇐ |
小于或等于 |
L → R |
p ⇐ q |
9 |
> |
Greater than |
L → R |
p > q |
9 |
>= |
大于或等于 |
L → R |
p >= q |
10 |
== |
Equality |
L → R |
p == q |
10 |
!= |
Inequality |
L → R |
p != q |
10 |
=== |
Strict equality |
L → R |
p === q |
10 |
!== |
Strict inequality |
L → R |
p !== q |
11 |
& |
Bitwise AND |
L → R |
p & q |
12 |
^ |
Bitwise XOR |
L → R |
p ^ q |
13 |
Bitwise OR |
L → R |
||
p |
q |
14 |
&& |
Logical AND |
L → R |
p && q |
15 |
||
Logical OR |
L → R |
p |
||
q |
16 |
?? |
Nullish Coalescing |
R → L |
p ?? q |
17 |
= |
Assignment |
R → L |
p = q |
17 |
: |
Colon assignment |
R → L |
p : q |
17 |
+= |
Addition assignment |
R → L |
p += q |
17 |
-= |
Subtraction assignment |
R → L |
p -= q |
17 |
*= |
Multiplication assignment |
R → L |
p *= q |
17 |
/= |
Division assignment |
R → L |
p /= q |
17 |
%= |
Modulo assignment |
R → L |
p %= q |
17 |
**= |
Exponentiation assignment |
R → L |
p **= q |
17 |
<⇐ |
Left shift assignement |
R → L |
p <⇐ q |
17 |
>>= |
Right shift assignment |
R → L |
p >>= q |
17 |
>>>= |
Unsigned right shift assignment |
R → L |
p >>>= q |
17 |
&= |
Bitwise AND assignment |
R → L |
p &= q |
17 |
^= |
Bitwise XOR assignment |
R → L |
p ^= q |
17 |
= |
Bitwise OR assignment |
|
R → L |
p |
= q |
17 |
&&= |
Logical AND assignment |
R → L |
p &&= q |
17 |
|
= |
Logical OR assignement |
R → L |
p |
|
= q |
17 |
⇒ |
Arrow operator |
|
- |
(a, b )⇒ { // 函数代码} |
17 |
… |
Spread operator |
- |
[… arr] |
18 |
yield |
Pause / Resume |
R → L |
yield p; |
19 |
, |
Comma operator |
Examples
让我们通过简单的示例来理解运算符优先级。
Example
在下面的示例中,第一个表达式包含优先级相同的除法、取模和乘法运算符。因此,编译器将使用关联性规则,即乘法、除法和取模运算符从左到右。
因此,它将 30 除以 15,取 (30/15) 对 3 的模,并将 ((30/15)%3) 与 2 相乘。
在第二个表达式中,指数运算符具有从右到左的关联性。因此,它将表达式求值为与 (2 8 (3 * 2)) 相同。
<html>
<body>
<div id = "output"></div>
<script>
const first = 30 / 15 % 3 * 2;
const second = 2 ** 3 ** 2;
document.getElementById("output").innerHTML =
"The value of first expression is : " + first + "<br>" +
"The value of second expression is : " + second;
</script>
</body>
</html>
Example
此代码演示了如何使用分组运算符 () 来更改运算符优先级。在以下代码中,我们使用了与上述代码中相同表达式,但我们更改了运算符优先级。
在第一个表达式中,我们首先取模,然后将结果值乘以 2。因此,我们得 0,并将 30 除以 0,返回无穷大。
在第二个表达式中,第一个表达式计算 (2 * 3) 和 (8 * 2),等于 64。
<html>
<body>
<div id = "output"></div>
<script>
const first = 30 / ((15 % 3) * 2);
const second = (2 ** 3) ** 2;
document.getElementById("output").innerHTML =
"The value of first expression is : " + first + "<br>" +
"The value of second expression is : " + second;
</script>
</body>
</html>