--- 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 OP1 b) OP2 c` のように処理されることであり、右結合(右から左)は `a OP1 (b OP2 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)}} | なし | ( … ) |
18 | {{jsxref("Operators/Property_Accessors", "メンバーへのアクセス", "#Dot_notation", 1)}} | 左から右 | … . … |
{{jsxref("Operators/Property_Accessors", "計算値によるメンバーへのアクセス","#Bracket_notation", 1)}} | 左から右 | … [ … ] |
|
{{jsxref("Operators/new","new")}} (引数リスト付き) | なし | new … ( … ) |
|
関数呼び出し | 左から右 |
… ( … )
|
|
オプション連鎖 | 左から右 | ?. |
|
17 | {{jsxref("Operators/new","new")}} (引数リストなし) | 右から左 | new … |
16 | {{jsxref("Operators","後置インクリメント","#インクリメントとデクリメント", 1)}} | なし | … ++ |
{{jsxref("Operators","後置デクリメント","#インクリメントとデクリメント", 1)}} | … -- |
||
15 | 論理 NOT (!) | 右から左 | ! … |
ビットごとの NOT (~) | ~ … |
||
単項 + | + … |
||
単項 - | - … |
||
前置インクリメント | ++ … |
||
前置デクリメント | -- … |
||
{{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 | ビット単位 AND (&) | 左から右 | … & … |
7 | ビット単位 XOR (^) | 左から右 | … ^ … |
6 | ビット単位 OR (|) | 左から右 | … | … |
5 | 論理 AND (&&) | 左から右 | … && … |
4 | 論理 OR (||) | 左から右 | … || … |
Null 合体 (??) | 左から右 | … ?? … |
|
3 | 条件(三項)演算子 | 右から左 | … ? … : … |
2 | 代入 | 右から左 | … = … |
… += … |
|||
… -= … |
|||
… **= … |
|||
… *= … |
|||
… /= … |
|||
… %= … |
|||
… <<= … |
|||
… >>= … |
|||
… >>>= … |
|||
… &= … |
|||
… ^= … |
|||
… |= … |
|||
… &&= … |
|||
… ||= … |
|||
… ??= … |
|||
{{jsxref("Operators/yield", "yield")}} | 右から左 | yield … |
|
{{jsxref("Operators/yield*", "yield*")}} | yield* … |
||
1 | カンマ / シーケンス | 左から右 | … , … |