运算符的优先级决定了表达式中运算执行的先后顺序,优先级高的运算符最先被执行。
结合性决定了拥有相同优先级的运算符的执行顺序。考虑下面这个表达式:
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 | 按位或 | 从左到右 | foo | bar |
6 | 逻辑运算符(逻辑与) | 从左到右 | foo && bar |
5 | 逻辑运算符(逻辑或) | 从左到右 | foo || bar |
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 | ||
赋值运算符 | foo |= bar | ||
2 | yield | 从右到左 | yield foo |
yield* | yield* foo | ||
1 | 扩展运算符 | N/A | ...foo |
0 | 逗号运算符 | 从左到右 | foo, bar |