aboutsummaryrefslogtreecommitdiff
path: root/files/zh-tw/web/javascript/reference/operators/optional_chaining/index.html
diff options
context:
space:
mode:
Diffstat (limited to 'files/zh-tw/web/javascript/reference/operators/optional_chaining/index.html')
-rw-r--r--files/zh-tw/web/javascript/reference/operators/optional_chaining/index.html195
1 files changed, 195 insertions, 0 deletions
diff --git a/files/zh-tw/web/javascript/reference/operators/optional_chaining/index.html b/files/zh-tw/web/javascript/reference/operators/optional_chaining/index.html
new file mode 100644
index 0000000000..a0b8edeae6
--- /dev/null
+++ b/files/zh-tw/web/javascript/reference/operators/optional_chaining/index.html
@@ -0,0 +1,195 @@
+---
+title: 可選串連
+slug: Web/JavaScript/Reference/Operators/Optional_chaining
+tags:
+ - JavaScript
+ - 串連
+ - 可選串連
+ - 語言功能
+ - 運算子
+translation_of: Web/JavaScript/Reference/Operators/Optional_chaining
+---
+<div>{{JSSidebar("Operators")}}</div>
+
+<div></div>
+
+<p><strong>可選串連</strong>運算子 <strong><code>?.</code></strong> 允許進行深層次的物件值存取,而無需透過明確的物件值串連驗證。<span class="seoSummary"><code>?.</code> 運算子的操作與 <code>.</code> 屬性存取運算子相似,後者會在參照到 <a href="/zh-TW/docs/Glossary/nullish">nullish</a> ({{JSxRef("null")}} or {{JSxRef("undefined")}}) 的值時出現錯誤,而前者可選串連則回傳 <code>undefined</code> 。</span> 當需要存取一個函數,而這函數並不存在時,則會回傳 <code>undefined</code> 。</p>
+
+<p>當有機會存在參照不存在的時候,可選串連可以提供更簡短的表述式來進行串連性的屬性存取。這有助於在無法保證物件屬性為必要存在的狀況下,進行物件內容的探索。</p>
+
+<div>{{EmbedInteractiveExample("pages/js/expressions-optionalchainingoperator.html", "taller")}}</div>
+
+<div></div>
+
+
+
+<h2 id="語法">語法</h2>
+
+<pre class="syntaxbox"><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="描述">描述</h2>
+
+<p>當串連物件裡面的參照或方法可能是<code>undefined</code> 或 <code>null</code> 時,可選串連運算子提供簡單的方法去存取這些串連物件下的值。</p>
+
+<p>舉例來說,當一個物件 <code>obj</code> 是巢狀結構時,在沒有可選串連之下,要去查找一深層的屬性值需要驗證每層間的參照連結:</p>
+
+<pre class="brush: js">let nestedProp = obj.first &amp;&amp; obj.first.second;</pre>
+
+<p><code>obj.first</code> 的值需要先確定不是 <code>null</code> 值(和並非 <code>undefined</code> ),才能存取 <code>obj.first.second</code> 的值。這才能避免在存取值時,因為直接使用 <code>obj.first.second</code> 而沒有測試 <code>obj.first</code> 之下帶來的錯誤。</p>
+
+<p>當使用了可選串連運算子(<code>?.</code>),你不再需要明確地進行測測,並能在基於 <code>obj.first</code> 的狀態下直接回傳,忽略存取 <code>obj.first.second</code> 的動作:</p>
+
+<pre class="brush: js">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">let temp = obj.first;
+let nestedProp = ((temp === null || temp === undefined) ? undefined : temp.second);
+</pre>
+
+<h3 id="可選串連呼叫函數">可選串連呼叫函數</h3>
+
+<p>你可以使用可選串連來嘗試呼叫一個或許沒有存在的方法。這可能有助於,舉例來說,使用一些未能提供服務的 API ,這可能因為過時的應用或是使用者的裝置未能支援某種功能。</p>
+
+<p>當需要使用的方法並不存在時,透過可選串連去進行呼叫將不會抛出錯誤,取而代之的是回傳 <code>undefined</code> :</p>
+
+<pre class="brush: js">let result = someInterface.customMethod?.();</pre>
+
+<div class="blockIndicator note">
+<p><strong>注意:</strong> 假如物件有同樣的屬性名稱,而不是一個方法,使用 <code>?.</code> 將會抛出 {{JSxRef("TypeError")}} 錯誤(<code>x.y</code><code> 不是一個函數</code>.</p>
+</div>
+
+<h4 id="處理回呼函式或事件處理器">處理回呼函式或事件處理器</h4>
+
+<p>如果你使用回呼函式,或是透過<a href="/zh-TW/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Object_destructuring">解構賦值</a>來擷取物件中的方法,你可能會因為這些方法沒有存在,而無法進行呼叫,除非你事先驗證其存在性。所以,你可以利用 <code>?.</code> 來避免這樣的測試:</p>
+
+<pre class="brush: js">// 在 ES2019 下撰寫
+function doSomething(onContent, onError) {
+ try {
+ // ... 對資料進行一些處理
+ }
+ catch (err) {
+ if (onError) { // 測試 onError 是否真的存在
+ onError(err.message);
+ }
+ }
+}
+</pre>
+
+<pre class="brush: js">// 使用可選串連進行函式呼叫
+function doSomething(onContent, onError) {
+ try {
+ // ... 對資料進行一些處理
+ }
+ catch (err) {
+ onError?.(err.message); // 就算 onError 是 undefined 也不會抛出錯誤
+ }
+}
+</pre>
+
+<h3 id="可選串連表述式">可選串連表述式</h3>
+
+<p>你也可以在<a href="/zh-TW/docs/Web/JavaScript/Reference/Operators/Property_Accessors#Bracket_notation">方括號屬性存取</a>表達式中使用可選串連:</p>
+
+<pre class="brush: js">let nestedProp = obj?.['prop' + 'Name'];
+</pre>
+
+<h3 id="矩陣項目的可選串連">矩陣項目的可選串連</h3>
+
+<pre class="brush: js">let arrayItem = arr?.[42];</pre>
+
+<h2 id="範例">範例</h2>
+
+<h3 id="基本範例">基本範例</h3>
+
+<p>這個範例會找出 Map 物件中一個鍵為 <code>bar</code> 成員的 <code>name</code> 屬性值,但事實上並沒有相關成員。所以結果為 <code>undefined</code> 。</p>
+
+<pre class="brush: js">let myMap = new Map();
+myMap.set("foo", {name: "baz", desc: "inga"});
+
+let nameBar = myMap.get("bar")?.name;</pre>
+
+<h3 id="短路式運算">短路式運算</h3>
+
+<p>當可選串連接上表述式時,如果左邊的運算數值是 <code>null</code> 或 <code>undefined</code> ,表述式則不會被運算。舉例來說:</p>
+
+<pre class="brush: js">let potentiallyNullObj = null;
+let x = 0;
+let prop = potentiallyNullObj?.[x++];
+
+console.log(x); // 因為 x 沒有遞增,所以為 0
+</pre>
+
+<h3 id="串接多個可選串連">串接多個可選串連</h3>
+
+<p>在巢狀結構中可以使用多次的可選串連:</p>
+
+<pre class="brush: js">let customer = {
+ name: "Carl",
+ details: {
+ age: 82,
+ location: "Paradise Falls" // 詳細地址 address 並不知道
+ }
+};
+let customerCity = customer.details?.address?.city;
+
+// … 同樣地,串接多個可選串連來呼叫函式也是湊效的
+let duration = vacations.trip?.getTime?.();
+</pre>
+
+<h3 id="使用空值合併運算子">使用空值合併運算子</h3>
+
+<p>在可選串連後可以使用{{JSxRef("Operators/Nullish_Coalescing_Operator", "空值合併運算子", '', 1)}}來編配預設值,如果無法在屬性串連中取得值:</p>
+
+<pre class="brush: js">let customer = {
+ name: "Carl",
+ details: { age: 82 }
+};
+const customerCity = customer?.city ?? "Unknown city";
+console.log(customerCity); // Unknown city</pre>
+
+<h2 id="規範">規範</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">Proposal for the "optional chaining" operator</a></td>
+ <td>Stage 4</td>
+ <td></td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="瀏覽器相容性">瀏覽器相容性</h2>
+
+<div>
+
+
+<p>{{Compat("javascript.operators.optional_chaining")}}</p>
+</div>
+
+<h3 id="實施進程">實施進程</h3>
+
+<p>因為本功能尚未達到跨瀏覽器性穩定,以下表格提供本功能的每天實驗狀態。資料是透過在各瀏覽器 nightly build 或最新版本 JavaScript 引擎中,進行<a href="https://github.com/tc39/test262">Test262</a> (一個 JavaScript 的標準測試包) 中相關測試而生成的。</p>
+
+<div>{{EmbedTest262ReportResultsTable("optional-chaining")}}</div>
+
+<h2 id="參見">參見</h2>
+
+<ul>
+ <li>{{JSxRef("Operators/Nullish_Coalescing_Operator", "空值合併運算子", '', 1)}}</li>
+ <li><a href="https://github.com/tc39/proposals">TC39 proposals</a></li>
+</ul>