运算符优先级
运算符的优先级决定了表达式中运算执行的先后顺序,优先级高的运算符最先被执行。
结合性
结合性决定了拥有相同优先级的运算符的执行顺序。考虑下面这个表达式:
a OP b OP c
-
左结合(左到右)相当于把左边的子表达式加上小括号
(a OP b) OP c
-
右关联(右到左)相当于
a OP (b OP c)
赋值运算符是右关联的,所以你可以这么写:
a = b = 5;
结果:a
和 b
的值都会成为 5。这是因为赋值运算符的返回结果就是赋值运算符右边的那个值,具体过程是:b
被赋值为 5,然后 a
也被赋值为 b=5
的返回值,也就是 5。
汇总表
以下示例中使用 foo
和 bar
作为演示变量或表达式。
优先级 | 运算类型 | 关联性 | 运算符示例 |
---|---|---|---|
20 | 分组表达式 | N/A | (foo) |
19 | 属性访问器 | 从左到右 | foo.bar |
属性访问器 | 从左到右 | foo[bar] |
|
实例化对象(带参数列表) | N/A | new Foo(bar) |
|
函数调用 | 从左到右 | foo() |
|
18 | 实例化对象(无参数列表) | 从左到右 | new Foo |
17 | 更新表达式(后置递增) | N/A | foo++ |
更新表达式(后置递减) | N/A | foo-- |
|
16 | 逻辑运算符(逻辑非) | 从右到左 | !foo |
按位非 | ~foo |
||
一元加法 | +foo |
||
一元减法 | -foo |
||
更新表达式(前置递增) | ++foo |
||
更新表达式(前置递减) | --foo |
||
typeof | typeof foo |
||
void | void foo |
||
delete | delete foo |
||
await | await foo |
||
15 | 算术运算符(幂) | 从右到左 | foo ** bar |
14 | 算术运算符(乘法) | 从左到右 | foo * bar |
算术运算符(除法) | foo / bar |
||
算术运算符(取模) | foo % bar |
||
13 | 算术运算符(加法) | 从左到右 | foo + bar |
算术运算符(减法) | foo - bar |
||
12 | 按位左移 | 从左到右 | foo << bar |
按位右移 | foo >> bar |
||
无符号右移 | ... >>> bar |
||
11 | 小于 | 从左到右 | foo < bar |
小于等于 | foo <= bar |
||
大于 | foo > bar |
||
大于等于 | foo >= bar |
||
in | foo in bar |
||
instanceof | foo instance bar |
||
10 | 等号 | 从左到右 | foo == bar |
非等号 | foo !== bar |
||
全等号 | foo === bar |
||
非全等号 | foo !== bar |
||
9 | 按位与 | 从左到右 | foo & bar |
8 | 按位异或 | 从左到右 | foo ^ bar |
7 | 按位或 | 从左到右 | <code>foo | bar</code> |
6 | 逻辑运算符(逻辑与) | 从左到右 | foo && bar |
5 | 逻辑运算符(逻辑或) | 从左到右 | <code>foo || bar</code> |
4 | 条件运算符 | 从右到左 | foo ? foo : bar |
3 | 赋值运算符 | 从右到左 | foo = bar |
赋值运算符 | foo += bar |
||
赋值运算符 | foo -= bar |
||
赋值运算符 | foo *= bar |
||
赋值运算符 | foo /= bar |
||
赋值运算符 | foo %= bar |
||
赋值运算符 | foo <<= bar |
||
赋值运算符 | foo >>= bar |
||
赋值运算符 | foo >>>= bar |
||
赋值运算符 | foo &= bar |
||
赋值运算符 | foo ^= bar |
||
赋值运算符 | <code> foo |= bar</code> | ||
2 | yield | 从右到左 | yield foo |
yield* | yield* foo |
||
1 | 扩展运算符 | N/A | ...foo |
0 | 逗号运算符 | 从左到右 | foo, bar |