--- title: 运算符优先级 slug: Web/JavaScript/Reference/Operators/Operator_Precedence tags: - 指南 - JavaScript - 优先级 translation_of: Web/JavaScript/Reference/Operators/Operator_Precedence --- {{jsSidebar("Operators")}} **运算符的优先级**决定了表达式中运算执行的先后顺序。优先级高的运算符会作为优先级低的运算符的操作符。 {{EmbedInteractiveExample("pages/js/expressions-operatorprecedence.html")}} ## 优先级和结合性 考虑由下面的表示法描述的表达式。其中,OP1 和 OP2 都是操作符的占位符。 ```js a OP1 b OP2 c ``` 如果 `OP1` 和 `OP2` 具有不同的优先级(见下表),则优先级最高的运算符先执行,不用考虑结合性。观察乘法如何具有比加法更高的优先级并首先执行,即使加法是首先写入代码的。 ```js console.log(3 + 10 * 2); // 输出 23 console.log(3 + (10 * 2)); // 输出 23 因为这里的括号是多余的 console.log((3 + 10) * 2); // 输出 26 因为括号改变了优先级 ``` 左结合(左到右)相当于把左边的子表达式加上小括号 `(a OP b) OP c`,右结合(右到左)相当于 `a OP (b OP c)`。赋值运算符是右结合的,所以你可以这么写: ```js a = b = 5; // 相当于 a = (b = 5); ``` 预期结果是 `a` 和 `b` 的值都会成为 5。这是因为赋值运算符的返回结果就是赋值运算符右边的那个值,具体过程是:首先 `b` 被赋值为 5,然后 `a` 也被赋值为 `b = 5` 的返回值,也就是 5。 另一个例子是,只有幂运算符是右结合的,而其他算术运算符都是左结合的。有趣的是,无论结合性和优先级如何,求值顺序总是从左到右。
代码 | 输出 |
function echo(name, num) { console.log("Evaluating the " + name + " side"); return num; } // 注意这里的除法运算符 (/) console.log(echo("left", 6) / echo("right", 2)); |
Evaluating the left side Evaluating the right side 3 |
function echo(name, num) { console.log("Evaluating the " + name + " side"); return num; } // 注意这里的幂运算符 (**) console.log(echo("left", 2) ** echo("right", 3)); |
Evaluating the left side Evaluating the right side 8 |
代码 | 输出 |
function echo(name, num) { console.log("Evaluating the " + name + " side"); return num; } // 注意这里的除法运算符 (/) console.log(echo("left", 6) / echo("middle", 2) / echo("right", 3)); |
Evaluating the left side Evaluating the middle side Evaluating the right side 1 |
function echo(name, num) { console.log("Evaluating the " + name + " side"); return num; } // 注意这里的幂运算符 (**) console.log(echo("left", 2) ** echo("middle", 3) ** echo("right", 2)); |
Evaluating the left side Evaluating the middle side Evaluating the right side 512 |
function echo(name, num) { console.log("Evaluating the " + name + " side"); return num; } // 注意这里左边和中间的被圆括号包围的求幂表达式 console.log((echo("left", 2) ** echo("middle", 3)) ** echo("right", 2)); |
Evaluating the left side Evaluating the middle side Evaluating the right side 64 |
优先级 | 运算符类型 | 结合性 | 运算符 |
---|---|---|---|
19 | {{jsxref("Operators/Grouping", "分组", "", 1)}} | n/a(不相关) | ( … ) |
18 | {{jsxref("Operators/Property_Accessors", "成员访问", "#点号表示法", 1)}} | 从左到右 | … . … |
{{jsxref("Operators/Property_Accessors", "需计算的成员访问", "#方括号表示法", 1)}} | 从左到右 | … [ … ] |
|
{{jsxref("Operators/new","new")}}(带参数列表) | n/a | new … ( … ) |
|
函数调用 | 从左到右 | … ( … ) |
|
可选链(Optional chaining) | 从左到右 | ?. |
|
17 | {{jsxref("Operators/new","new")}}(无参数列表) | 从右到左 | new … |
16 | {{jsxref("Operators","后置递增","#自增和自减", 1)}} | n/a | … ++ |
{{jsxref("Operators","后置递减","#自增和自减", 1)}} | … -- |
||
15 | 逻辑非 (!) | 从右到左 | ! … |
按位非 (~) | ~ … |
||
一元加法 (+) | + … |
||
一元减法 (-) | - … |
||
{{jsxref("Operators","前置递增","#自增和自减", 1)}} | ++ … |
||
{{jsxref("Operators","前置递减","#自增和自减", 1)}} | -- … |
||
{{jsxref("Operators/typeof", "typeof")}} | typeof … |
||
{{jsxref("Operators/void", "void")}} | void … |
||
{{jsxref("Operators/delete", "delete")}} | delete … |
||
{{jsxref("Operators/await", "await")}} | await … |
||
14 | 幂 (**) | 从右到左 | … ** … |
13 | 乘法 (*) | 从左到右 | … * … |
除法 (/) | … / … |
||
取余 (%) | … % … |
||
12 | 加法 (+) | 从左到右 | … + … |
减法 (-) | … - … |
||
11 | 按位左移 (<<) | 从左到右 | … << … |
按位右移 (>>) | … >> … |
||
无符号右移 (>>>) | … >>> … |
||
10 | 小于 (<) | 从左到右 | … < … |
小于等于 (<=) | … <= … |
||
大于 (>) | … > … |
||
大于等于 (>=) | … >= … |
||
{{jsxref("Operators/in", "in")}} | … in … |
||
{{jsxref("Operators/instanceof", "instanceof")}} | … instanceof … |
||
9 | 相等 (==) | 从左到右 | … == … |
不相等 (!=) | … != … |
||
一致/严格相等 (===) | … === … |
||
不一致/严格不相等 (!==) | … !== … |
||
8 | 按位与 (&) | 从左到右 | … & … |
7 | 按位异或 (^) | 从左到右 | … ^ … |
6 | 按位或 (|) | 从左到右 | … | … |
5 | 逻辑与 (&&) | 从左到右 | … && … |
4 | 逻辑或 (||) | 从左到右 | … || … |
空值合并 (??) | 从左到右 | … ?? … |
|
3 | 条件(三元)运算符 | 从右到左 | … ? … : … |
2 | 赋值 | 从右到左 | … = … |
… += … |
|||
… -= … |
|||
… **= … |
|||
… *= … |
|||
… /= … |
|||
… %= … |
|||
… <<= … |
|||
… >>= … |
|||
… >>>= … |
|||
… &= … |
|||
… ^= … |
|||
… |= … |
|||
… &&= … |
|||
… ||= … |
|||
… ??= … |
|||
1 | 逗号 / 序列 | 从左到右 | … , … |