diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
commit | 33058f2b292b3a581333bdfb21b8f671898c5060 (patch) | |
tree | 51c3e392513ec574331b2d3f85c394445ea803c6 /files/ja/web/javascript/reference/operators/optional_chaining | |
parent | 8b66d724f7caf0157093fb09cfec8fbd0c6ad50a (diff) | |
download | translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.gz translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.bz2 translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.zip |
initial commit
Diffstat (limited to 'files/ja/web/javascript/reference/operators/optional_chaining')
-rw-r--r-- | files/ja/web/javascript/reference/operators/optional_chaining/index.html | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/files/ja/web/javascript/reference/operators/optional_chaining/index.html b/files/ja/web/javascript/reference/operators/optional_chaining/index.html new file mode 100644 index 0000000000..e7d213f8fa --- /dev/null +++ b/files/ja/web/javascript/reference/operators/optional_chaining/index.html @@ -0,0 +1,203 @@ +--- +title: Optional chaining (?.) +slug: Web/JavaScript/Reference/Operators/Optional_chaining +tags: + - Chaining + - JavaScript + - Language feature + - Operator + - Optional chaining + - Reference +translation_of: Web/JavaScript/Reference/Operators/Optional_chaining +--- +<div>{{JSSidebar("Operators")}}</div> + +<p><ruby><strong>オプショナルチェイニング</strong><rp> (</rp><rt>optional chaining</rt><rp>) </rp></ruby>演算子 <strong><code>?.</code></strong> は、接続されたオブジェクトチェーンの深くに位置するプロパティの値を、チェーン内の各参照が正しいかどうかを明示的に確認せずに読み込むことを可能にします。 <span class="seoSummary"><code>?.</code> 演算子の機能は <code>.</code> チェーン演算子と似ていますが、参照が {{glossary("nullish")}} ({{JSxRef("null")}} または {{JSxRef("undefined")}}) の場合にエラーとなるのではなく、式が短絡され <code>undefined</code> が返されるところが異なります。</span> 関数呼び出しで使用すると、与えられた関数が存在しない場合、 <code>undefined</code> を返します。</p> + +<p>これは、参照が失われた可能性のある連結されたプロパティにアクセスする時、結果的に短く単純な式になります。また、必要なプロパティの存在が保証されていない場合にオブジェクトのコンテンツを探索するのにも役立ちます。</p> + +<p>オプショナルチェイニングは、存在しないルートオブジェクトでは使用できません。<code>if (typeof a == "undefined")</code> のようなチェックを置き換えるものではありません。</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-optionalchainingoperator.html", "taller")}}</div> + +<div class="hidden">このデモのソースファイルは GitHub リポジトリに格納されています。デモプロジェクトに協力したい場合は、 <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> をクローンしてプルリクエストを送信してください。</div> + +<h2 id="Syntax" name="Syntax">構文</h2> + +<pre class="syntaxbox notranslate"><var>obj</var>?.<var>prop</var> +<var>obj</var>?.[<var>expr</var>] +<em>arr</em>?.[<var>index</var>] +<var>func</var>?.(<var>args</var>) +</pre> + +<h2 id="Description" name="Description">解説</h2> + +<p>オプショナルチェイニング演算子は、参照や関数が <code>undefined</code> または <code>null</code> である可能性がある場合でも、接続されたオブジェクトの値に簡単にアクセスする手段を提供します。</p> + +<p>たとえば、入れ子構造を持つオブジェクト <code>obj</code> を考えましょう。オプショナルチェイニング演算子なしで深い入れ子になったサブプロパティにアクセスするには、次のように、各プロパティ間の参照を確認する必要があります:</p> + +<pre class="brush: js notranslate">let nestedProp = obj.first && obj.first.second;</pre> + +<p><code>obj.first.second</code> の値にアクセスする前に、 <code>obj.first</code> の値が <code>null</code> または <code>undefined</code> でないことを確認します。これにより、 <code>obj.first</code> をテストせずに直接 <code>obj.first.second</code> にアクセスしたときに起きるエラーを防ぐことができます。</p> + +<p>しかし、オプショナルチェイニング演算子 (<code>?.</code>) を使えば、<code>obj.first.second</code> にアクセスしようとする前に <code>obj.first</code> の状態を明示的にテストする必要がなくなります:</p> + +<pre class="brush: js notranslate">let nestedProp = obj.first?.second;</pre> + +<p><code>?.</code> を <code>.</code> の代わりに用いることで、 JavaScript が <code>obj.first.second</code> にアクセスしようとする前に <code>obj.first</code> が <code>null</code> または <code>undefined</code> でないことを暗黙的に確かめるようになります。<code>obj.first</code> が <code>null</code> または <code>undefined</code> であった場合、式が自動的に短絡され、 <code>undefined</code> が返ります。</p> + +<p>これは、一時的な変数が作成されないことを除き、次の式と等価です。</p> + +<pre class="brush: js notranslate">let temp = obj.first; +let nestedProp = ((temp === null || temp === undefined) ? undefined : temp.second); +</pre> + +<h3 id="Optional_chaining_with_function_calls" name="Optional_chaining_with_function_calls">関数呼び出しでオプショナルチェイニング演算子を使う</h3> + +<p>存在しない可能性がある関数の呼び出しを試行するときに、オプショナルチェイニングを使うことができます。これはたとえば、ユーザーのデバイス上で使えなかったり、実装が古かったりするために使えなかったりする可能性がある API を使うときに役立ちます。</p> + +<p>関数呼び出しでオプショナルチェイニング演算子を用いた場合、メソッドが見つからないときは自動的に <code>undefined</code> が返ります。例外はスローされません。</p> + +<pre class="brush: js notranslate">let result = someInterface.customMethod?.();</pre> + +<div class="blockIndicator note"> +<p><strong>注意:</strong> 上記のようなプロパティの関数がない場合に、<code>?.</code> を使用すると {{JSxRef("TypeError")}} 例外が発生します (<code>someInterface.customMethod is not a function</code>)。</p> +</div> + +<div class="blockIndicator note"> +<p><strong>注意:</strong> <code>someInterface</code> 自体が <code>null</code> または <code>undefined</code> の場合にも、{{JSxRef("TypeError")}} 例外が発生します (<code>someInterface is null</code>)。<code>someInterface</code> 自体が <code>null</code> または <code>undefined</code> の可能性がある場合は、次の位置にも <code>?.</code> を使用しなければなりません。<code>someInterface?.customMethod?.()</code></p> +</div> + +<h4 id="Dealing_with_optional_callbacks_or_event_handlers" name="Dealing_with_optional_callbacks_or_event_handlers">省略可能なコールバックやイベントハンドラを扱う</h4> + +<p>コールバックを使う場合や、オブジェクトからメソッドを<a href="/ja/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">分割代入</a>を利用して取り出す場合に、存在しない値がある可能性があり、その存在を検証するまで関数として呼び出せません。その場合 <code>?.</code> を利用することで、検証の必要性を回避できます。</p> + +<pre class="brush: js notranslate">// Written as of ES2019 +function doSomething(onContent, onError) { + try { + // ... do something with the data + } + catch (err) { + if (onError) { // Testing if onError really exists + onError(err.message); + } + } +} +</pre> + +<pre class="brush: js notranslate">// Using optional chaining with function calls +function doSomething(onContent, onError) { + try { + // ... do something with the data + } + catch (err) { + onError?.(err.message); // no exception if onError is undefined + } +} +</pre> + +<h3 id="Optional_chaining_with_expressions" name="Optional_chaining_with_expressions">オプショナルチェイニング演算子を式と組み合わせて使う</h3> + +<p><a href="/ja/docs/Web/JavaScript/Reference/Operators/Property_Accessors#Bracket_notation">ブラケット表記法</a>とオプショナルチェイニング演算子を組み合わせることもできます。</p> + +<pre class="brush: js notranslate">let nestedProp = obj?.['prop' + 'Name']; +</pre> + +<h3 id="Optional_chaining_not_valid_on_the_left-hand_side_of_an_assignment" name="Optional_chaining_not_valid_on_the_left-hand_side_of_an_assignment">オプショナルチェイニング演算子は代入の左辺値では有効にならない</h3> + +<pre class="brush: js notranslate"><code>let object = {}; +object?.property = 1; // Uncaught SyntaxError: Invalid left-hand side in assignment</code></pre> + +<h3 id="オプショナルチェイニングにより配列の要素にアクセス">オプショナルチェイニングにより配列の要素にアクセス</h3> + +<pre class="brush: js notranslate">let arrayItem = arr?.[42];</pre> + +<h2 id="Examples" name="Examples">例</h2> + +<h3 id="Basic_example" name="Basic_example">基本的な例</h3> + +<p>次の例では、マップに存在しない <code>bar</code> メンバの <code>name</code> プロパティを取得しようとしています。したがって、結果は <code>undefined</code> になります。</p> + +<pre class="brush: js notranslate">let myMap = new Map(); +myMap.set("foo", {name: "baz", desc: "inga"}); + +let nameBar = myMap.get("bar")?.name;</pre> + +<h3 id="Short-circuiting_evaluation" name="Short-circuiting_evaluation">短絡評価</h3> + +<p>式と一緒にオプショナルチェイニング演算子を用いたとき、左側のオペランドが <code>null</code> または <code>undefined</code> である場合にその式は評価されなくなります。</p> + +<pre class="brush: js notranslate">let potentiallyNullObj = null; +let x = 0; +let prop = potentiallyNullObj?.[x++]; + +console.log(x); // 0 as x was not incremented +</pre> + +<h3 id="Stacking_the_optional_chaining_operator" name="Stacking_the_optional_chaining_operator">オプショナルチェイニングをつなげて使う</h3> + +<p>入れ子になったオブジェクトでは、オプショナルチェイニング演算子を何度でも使えます。</p> + +<pre class="brush: js notranslate">let customer = { + name: "Carl", + details: { + age: 82, + location: "Paradise Falls" // detailed address is unknown + } +}; +let customerCity = customer.details?.address?.city; + +// … this also works with optional chaining function call +let duration = vacations.trip?.getTime?.(); +</pre> + +<h3 id="Combining_with_the_nullish_coalescing_operator" name="Combining_with_the_nullish_coalescing_operator">Null 合体演算子と共に使う</h3> + +<p>{{JSxRef("Operators/Nullish_Coalescing_Operator", "Null 合体演算子", '', 1)}}はオプショナルチェイニングの後につけることで、存在しない値があった時、既定値をかわりに使うために利用できます。</p> + +<pre class="brush: js notranslate">let customer = { + name: "Carl", + details: { age: 82 } +}; +const customerCity = customer?.city ?? "Unknown city"; +console.log(customerCity); // Unknown city</pre> + +<h2 id="Specifications" name="Specifications">仕様</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">仕様書</th> + <th scope="col">状態</th> + <th scope="col">備考</th> + </tr> + </thead> + <tbody> + <tr> + <td><a href="https://tc39.es/proposal-optional-chaining/#sec-scope">"オプショナルチェイニング" 演算子の提案</a></td> + <td>Stage 4</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザーの互換性</h2> + +<div> +<div class="hidden">このページの互換性一覧表は構造化データから生成されています。データに協力していただけるのであれば、 <a class="external" href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> をチェックアウトしてプルリクエストを送信してください。</div> + +<p>{{Compat("javascript.operators.optional_chaining")}}</p> +</div> + +<h3 id="Implementation_Progress" name="Implementation_Progress">実装の進捗</h3> + +<p>この機能はまだブラウザー間相互運用の安定性に達していないため、以下の表はこの機能の日々の実装状況を示しています。このデータは、 JavaScript の標準テストスイートである <a href="https://github.com/tc39/test262">Test262</a> で、該当する機能テストを毎晩のビルド、または各ブラウザーの JavaScript エンジンの最新リリースで実行することで生成されます。</p> + +<div>{{EmbedTest262ReportResultsTable("optional-chaining")}}</div> + +<h2 id="See_also" name="See_also">関連情報</h2> + +<ul> + <li>{{JSxRef("Operators/Nullish_Coalescing_Operator", "Null 合体演算子", '', 1)}}</li> + <li><a href="https://github.com/tc39/proposals">TC39 proposals</a></li> +</ul> |