From 857589c6b524b237e438e0ec972e0aa9539838cd Mon Sep 17 00:00:00 2001 From: Masahiro FUJIMOTO Date: Sat, 12 Oct 2024 22:49:53 +0900 Subject: [PATCH] =?UTF-8?q?2024/07/29=20=E6=99=82=E7=82=B9=E3=81=AE?= =?UTF-8?q?=E8=8B=B1=E8=AA=9E=E7=89=88=E3=81=AB=E5=9F=BA=E3=81=A5=E3=81=8D?= =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../operators/nullish_coalescing/index.md | 95 ++++++++++--------- 1 file changed, 49 insertions(+), 46 deletions(-) diff --git a/files/ja/web/javascript/reference/operators/nullish_coalescing/index.md b/files/ja/web/javascript/reference/operators/nullish_coalescing/index.md index 1ecd7e707d4d13..888871c7078019 100644 --- a/files/ja/web/javascript/reference/operators/nullish_coalescing/index.md +++ b/files/ja/web/javascript/reference/operators/nullish_coalescing/index.md @@ -1,22 +1,39 @@ --- title: Null 合体演算子 (??) slug: Web/JavaScript/Reference/Operators/Nullish_coalescing +l10n: + sourceCommit: 59a92ab5609f0a021602f11843f3b00b16e67e6d --- -{{JSSidebar("Operators")}} +{{jsSidebar("Operators")}} **Null 合体演算子 (`??`)** は論理演算子の一種です。この演算子は左辺が [`null`](/ja/docs/Web/JavaScript/Reference/Operators/null) または {{jsxref("undefined")}} の場合に右の値を返し、それ以外の場合に左の値を返します。 -これは[論理 OR 演算子 (`||`)](/ja/docs/Web/JavaScript/Reference/Operators/Logical_OR) の特殊形と見なすことができます。そちらは左辺の値が `null` や `undefined` だけでなく、何らかの{{Glossary("falsy", "偽値")}}であった場合に右辺値を返すものです。つまり、 `||` を使って別の変数 `foo` に何らかの既定値を与える場合、一部の偽値(例えば `''` や `0`)を使用可能とみなすと、予想外の動作に遭遇することがあります。詳しい例は以下を参照してください。 +{{EmbedInteractiveExample("pages/js/expressions-nullishcoalescingoperator.html")}} + +## 構文 + +```js-nolint +leftExpr ?? rightExpr +``` + +## 解説 + +Null 合体演算子は、[論理 OR (`||`) 演算子](/ja/docs/Web/JavaScript/Reference/Operators/Logical_OR)の特殊形と見なすことができます。後者は左辺の値が `null` や `undefined` だけでなく、何らかの{{Glossary("falsy", "偽値")}}であった場合に右辺値を返すものです。言い換えると、`||` を使って別の変数 `foo` に何らかの既定値を与える場合、一部の偽値(`''` や `0` など)を使用可能とみなすと、予想外の動作に遭遇することがあります。詳しい例は以下を参照してください。 Null 合体演算子は[演算子の優先順位](/ja/docs/Web/JavaScript/Reference/Operators/Operator_precedence)が下から 5 番目で、 `||` のすぐ下、[条件(三項)演算子](/ja/docs/Web/JavaScript/Reference/Operators/Conditional_operator)のすぐ上とします。 -{{EmbedInteractiveExample("pages/js/expressions-nullishcoalescingoperator.html")}} +AND (`&&`) および OR 演算子 (`||`) のどちらも、直接 `??` と結合することはできません。このような場合、[構文エラー](/ja/docs/Web/JavaScript/Reference/Errors/Cant_use_nullish_coalescing_unparenthesized)が発生します。 -## 構文 +```js-nolint example-bad +null || undefined ?? "foo"; // SyntaxError が発生 +true && undefined ?? "foo"; // SyntaxError が発生 +``` -```js -leftExpr ?? rightExpr; +代わりに、括弧を使用して優先順位を明示的に指定してください。 + +```js example-good +(null || undefined) ?? "foo"; // "foo" を返す ``` ## 例 @@ -46,18 +63,18 @@ console.log(valC); // 42 ```js let foo; -// foo には何も値が代入されていないので、 undefined のままです -let someDummyText = foo || "Hello!"; +// foo には何も値が代入されていないので、undefined のままです +const someDummyText = foo || "Hello!"; ``` -しかし、`||` が論理演算子であるため、左辺の値は評価によって強制的に論理値になり、偽値(`0`, `''`, `NaN`, `null`, `undefined`)が返されることはありません。この動作は、 `0` や `''`, `NaN` を有効な値と考えている場合、予期せぬ結果を引き起こす可能性があります。 +しかし、`||` が論理演算子であるため、左辺の値は評価によって強制的に論理値になり、偽値(`0`, `''`, `NaN`, `false` など)が返されることはありません。この動作は、 `0` や `''`, `NaN` を有効な値と考えている場合、予期せぬ結果を引き起こす可能性があります。 ```js -let count = 0; -let text = ""; +const count = 0; +const text = ""; -let qty = count || 42; -let message = text || "hi!"; +const qty = count || 42; +const message = text || "hi!"; console.log(qty); // 42 であり 0 ではない console.log(message); // "hi!" であり "" ではない ``` @@ -65,64 +82,49 @@ console.log(message); // "hi!" であり "" ではない Null 合体演算子は、左辺の値が `null` もしくは `undefined` のどちらか(その他の falsy な値は含みません)に評価された場合にのみ右辺の値を返すことで、この潜在的な危険を回避します。 ```js -let myText = ""; // 空文字列(偽値) +const myText = ""; // 空文字列(すなわち偽値でもある) -let notFalsyText = myText || "Hello world"; +const notFalsyText = myText || "Hello world"; console.log(notFalsyText); // Hello world -let preservingFalsy = myText ?? "Hi neighborhood"; +const preservingFalsy = myText ?? "Hi neighborhood"; console.log(preservingFalsy); // '' (myText は undefined でも null でもない) ``` ### 短絡評価 -OR 演算子や AND 演算子と同様に、左辺が `null` でも `undefined` でもないことが判明した場合、右辺の式は評価されません。 +'OR' 演算子や 'AND' 演算子と同様に、左辺が `null` でも `undefined` でもないことが判明した場合、右辺の式は評価されません。 ```js -function A() { - console.log("A was called"); +function a() { + console.log("a が呼び出されました"); return undefined; } -function B() { - console.log("B was called"); +function b() { + console.log("b が呼び出されました"); return false; } -function C() { - console.log("C was called"); +function c() { + console.log("c が呼び出されました"); return "foo"; } -console.log(A() ?? C()); -// "A was called"、 "C was called" のあと "foo" と出力 +console.log(a() ?? c()); +// "A が呼び出されました"、 "C が呼び出されました" のあと "foo" と出力 // A() は undefined を返すため、両方の式が評価されるため -console.log(B() ?? C()); -// "B was called" のあと "false" と出力 +console.log(b() ?? c()); +// "B が呼び出されました" のあと "false" と出力 // B() は false を返すため(そして null も undefined も返さない)、 // 右辺の式は評価されない ``` -### AND 演算子、OR 演算子とつなげて使わない - -AND 演算子 (`&&`) と OR 演算子 (`||`) を直接 `??` と組み合わせて使うことはできません。このような場合 [`SyntaxError`](/ja/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError) が発生します。 - -```js example-bad -null || undefined ?? "foo"; // SyntaxError が発生 -true || undefined ?? "foo"; // SyntaxError が発生 -``` - -ただし、カッコを付けて明示的に優先順位を示すのは正しいやり方です。 - -```js example-good -(null || undefined) ?? "foo"; // "foo" を返す -``` - -### オプション連鎖演算子 (`?.`) との関係 +### オプショナルチェーン演算子 (`?.`) との関係 -Null 合体演算子は、 `undefined` と `null` を特定の値として扱いますが、[オプション連鎖演算子 (`?.`)](/ja/docs/Web/JavaScript/Reference/Operators/Optional_chaining) も同様の扱いをします。この演算子は、`null` または `undefined` である可能性のあるオブジェクトのプロパティにアクセスするのに便利です。 +Null 合体演算子は、 `undefined` と `null` を特定の値として扱いますが、[オプショナルチェーン演算子 (`?.`)](/ja/docs/Web/JavaScript/Reference/Operators/Optional_chaining) も同様の扱いをします。この演算子は、`null` または `undefined` である可能性のあるオブジェクトのプロパティにアクセスするのに便利です。 ```js -let foo = { someFooProp: "hi" }; +const foo = { someFooProp: "hi" }; console.log(foo.someFooProp?.toUpperCase() ?? "not available"); // "HI" console.log(foo.someBarProp?.toUpperCase() ?? "not available"); // "not available" @@ -138,6 +140,7 @@ console.log(foo.someBarProp?.toUpperCase() ?? "not available"); // "not availabl ## 関連情報 -- [オプション連鎖演算子](/ja/docs/Web/JavaScript/Reference/Operators/Optional_chaining) +- [Null 合体代入 (`??=`) 演算子](/ja/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_assignment) +- [オプショナルチェーン (`?.`) 演算子](/ja/docs/Web/JavaScript/Reference/Operators/Optional_chaining) - [論理 OR (`||`) 演算子](/ja/docs/Web/JavaScript/Reference/Operators/Logical_OR) - [デフォルト引数](/ja/docs/Web/JavaScript/Reference/Functions/Default_parameters)