From fcfc36cbe0ddfbaad1f821e9dd097d1668a10c42 Mon Sep 17 00:00:00 2001 From: Masahiro FUJIMOTO Date: Mon, 21 Feb 2022 02:28:49 +0900 Subject: Web/JavaScript/Reference/Operators/Operator_Precedence を移行 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../operators/operator_precedence/index.html | 481 --------------------- .../operators/operator_precedence/index.md | 481 +++++++++++++++++++++ 2 files changed, 481 insertions(+), 481 deletions(-) delete mode 100644 files/ja/web/javascript/reference/operators/operator_precedence/index.html create mode 100644 files/ja/web/javascript/reference/operators/operator_precedence/index.md (limited to 'files/ja/web/javascript') diff --git a/files/ja/web/javascript/reference/operators/operator_precedence/index.html b/files/ja/web/javascript/reference/operators/operator_precedence/index.html deleted file mode 100644 index 48cf7fe15e..0000000000 --- a/files/ja/web/javascript/reference/operators/operator_precedence/index.html +++ /dev/null @@ -1,481 +0,0 @@ ---- -title: 演算子の優先順位 -slug: Web/JavaScript/Reference/Operators/Operator_Precedence -tags: - - Guide - - JavaScript - - precedence - - ガイド - - 優先順位 -translation_of: Web/JavaScript/Reference/Operators/Operator_Precedence ---- -
{{jsSidebar("Operators")}}
- -

演算子の優先順位は、演算子が互いにどのように解析されるかを決定します。優先度の高い演算子は、優先度の低い演算子のオペランドになります。

- -
{{EmbedInteractiveExample("pages/js/expressions-operatorprecedence.html")}}
- - - -

優先度と結合性

- -

以下の表現で記述できる式を考えてみましょう。なお、OP1 と OP2 は演算子に置き換わります。

- -
a OP1 b OP2 c
- -

OP1OP2 の優先順位 (下記の一覧表を参照) が異なる場合は、優先順位の高い演算子が先に実行され、結合性は関係ありません。コードの中で加算が先に書かれているにもかかわらず、乗算の方が加算よりも優先順位が高く、先に実行されていることを確認してください。

- -
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) のように解釈されることです。代入演算子は右結合なので、このように書くことができます。

- -
a = b = 5; // a = (b = 5); と書いたのと同じ
-
- -

これで、ab が 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
-
- -

上記のコードを見てください。6 / 3 / 2 は、除算が左結合なので (6 / 3) / 2 と同じになります。一方で、べき乗は右結合なので、2 ** 3 ** 22 ** (3 ** 2) と同じになります。したがって、(2 ** 3) ** 2 とすると上記の表にある通り、演算順序が変わって結果が 64 になります。

- -

優先順位は結合度よりも優先されることを忘れないでください。そのため、割り算とべき乗を交ぜた場合、べき乗は割り算よりも先に計算されます。例えば 2 ** 3 / 3 ** 2 の結果は 0.8888888888888888 となります。これは (2 ** 3) / (3 ** 2) と同じだからです。

- -

グループ化と短絡の注意

- -

下記の表では、グループ化が最上位の優先順位を持つものとして挙げられています。しかし、特に短絡が発生する場合は、グループ化記号 ( … ) の中の式が最初に評価されるとは限りません。

- -

短絡は、条件付き評価を表す用語です。例えば、a && (b + c) という式において、a が {{Glossary("falsy")}} である場合、従属式である (b + c) は括弧で囲まれていても評価されません。この論理的分離演算子 ("OR") は「短絡的」といえるでしょう。論理的分離演算子の他にも、ほかに短絡が発生する演算子には、論理的結合 ("AND") 演算子、Null 合体演算子、オプションチェーン演算子、条件演算子があります。いかに例を示します。

- -
a || (b * c);  // `a` を最初に評価し、`a` が "truthy" であれば `a` を出力
-a && (b < c);  // `a` を最初に評価し、`a` が "falsy" であれば `a` を出力
-a ?? (b || c); // `a` を最初に評価し、`a` が `null` または `undefined` でなければ `a` を出力
-a?.b.c;        // `a` を最初に評価し、then produce `a` if `a` is `null` or `undefined`
-
- -

- -
3 > 2 && 2 > 1
-// returns true
-
-3 > 2 > 1
-// 結果は false となる。3 > 2 は true であり、true は
-// 不等号で 1 に変換されるため、true > 1 は 1 > 1 となり、
-// false となる。(3 > 2) > 1 のように括弧を付けると明確になる。
-
- -

一覧表

- -

以下の表は優先順位の最も高いもの (19) から最も低いもの (1) の順に並べられています。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
優先順位演算子の種類結合性演算子
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/Arithmetic_Operators","後置インクリメント","#Increment", 1)}}なし… ++
{{jsxref("Operators/Arithmetic_Operators","後置デクリメント","#Decrement", 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カンマ / シーケンス左から右… , …
diff --git a/files/ja/web/javascript/reference/operators/operator_precedence/index.md b/files/ja/web/javascript/reference/operators/operator_precedence/index.md new file mode 100644 index 0000000000..48cf7fe15e --- /dev/null +++ b/files/ja/web/javascript/reference/operators/operator_precedence/index.md @@ -0,0 +1,481 @@ +--- +title: 演算子の優先順位 +slug: Web/JavaScript/Reference/Operators/Operator_Precedence +tags: + - Guide + - JavaScript + - precedence + - ガイド + - 優先順位 +translation_of: Web/JavaScript/Reference/Operators/Operator_Precedence +--- +
{{jsSidebar("Operators")}}
+ +

演算子の優先順位は、演算子が互いにどのように解析されるかを決定します。優先度の高い演算子は、優先度の低い演算子のオペランドになります。

+ +
{{EmbedInteractiveExample("pages/js/expressions-operatorprecedence.html")}}
+ + + +

優先度と結合性

+ +

以下の表現で記述できる式を考えてみましょう。なお、OP1 と OP2 は演算子に置き換わります。

+ +
a OP1 b OP2 c
+ +

OP1OP2 の優先順位 (下記の一覧表を参照) が異なる場合は、優先順位の高い演算子が先に実行され、結合性は関係ありません。コードの中で加算が先に書かれているにもかかわらず、乗算の方が加算よりも優先順位が高く、先に実行されていることを確認してください。

+ +
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) のように解釈されることです。代入演算子は右結合なので、このように書くことができます。

+ +
a = b = 5; // a = (b = 5); と書いたのと同じ
+
+ +

これで、ab が 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
+
+ +

上記のコードを見てください。6 / 3 / 2 は、除算が左結合なので (6 / 3) / 2 と同じになります。一方で、べき乗は右結合なので、2 ** 3 ** 22 ** (3 ** 2) と同じになります。したがって、(2 ** 3) ** 2 とすると上記の表にある通り、演算順序が変わって結果が 64 になります。

+ +

優先順位は結合度よりも優先されることを忘れないでください。そのため、割り算とべき乗を交ぜた場合、べき乗は割り算よりも先に計算されます。例えば 2 ** 3 / 3 ** 2 の結果は 0.8888888888888888 となります。これは (2 ** 3) / (3 ** 2) と同じだからです。

+ +

グループ化と短絡の注意

+ +

下記の表では、グループ化が最上位の優先順位を持つものとして挙げられています。しかし、特に短絡が発生する場合は、グループ化記号 ( … ) の中の式が最初に評価されるとは限りません。

+ +

短絡は、条件付き評価を表す用語です。例えば、a && (b + c) という式において、a が {{Glossary("falsy")}} である場合、従属式である (b + c) は括弧で囲まれていても評価されません。この論理的分離演算子 ("OR") は「短絡的」といえるでしょう。論理的分離演算子の他にも、ほかに短絡が発生する演算子には、論理的結合 ("AND") 演算子、Null 合体演算子、オプションチェーン演算子、条件演算子があります。いかに例を示します。

+ +
a || (b * c);  // `a` を最初に評価し、`a` が "truthy" であれば `a` を出力
+a && (b < c);  // `a` を最初に評価し、`a` が "falsy" であれば `a` を出力
+a ?? (b || c); // `a` を最初に評価し、`a` が `null` または `undefined` でなければ `a` を出力
+a?.b.c;        // `a` を最初に評価し、then produce `a` if `a` is `null` or `undefined`
+
+ +

+ +
3 > 2 && 2 > 1
+// returns true
+
+3 > 2 > 1
+// 結果は false となる。3 > 2 は true であり、true は
+// 不等号で 1 に変換されるため、true > 1 は 1 > 1 となり、
+// false となる。(3 > 2) > 1 のように括弧を付けると明確になる。
+
+ +

一覧表

+ +

以下の表は優先順位の最も高いもの (19) から最も低いもの (1) の順に並べられています。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
優先順位演算子の種類結合性演算子
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/Arithmetic_Operators","後置インクリメント","#Increment", 1)}}なし… ++
{{jsxref("Operators/Arithmetic_Operators","後置デクリメント","#Decrement", 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カンマ / シーケンス左から右… , …
-- cgit v1.2.3-54-g00ecf