← Back to list

[筆記] ES2020 空值合併運算符 Nullish Coalescing Operator

ES2020 推出的「空值合併運算符 Nullish Coalescing Operator」相比過去常用的 Logical Operator(邏輯運算子) 在實作 Short Circuit 時,讓開發者能更輕鬆的撰寫程式碼,也讓程式碼更不容易出錯!

Mike Huang in 麥克的半路出家筆記 · 2023-02-10 18:38 · 110 claps · 8.2 min read paywalled
#javascript #frontend-development #notes #es2020 #ecmascript-2020
Open on Medium ↗
Wiki topics: 🌐 · Web Development

[筆記] JavaScript ES2020 空值合併運算符 Nullish Coalescing Operator (??)

在過去 Logical Operator(邏輯運算子) 讓開發者在撰寫程式碼時能夠更簡潔——其中最方便之處在於能讓我們能透過使用 ||&& 兩個邏輯運算子,像 if 般有條件的執行特定行為。這有鑒於 Logical Expression (邏輯運算式)的運作是由左到右執行,一旦第一個運算元(Operand)能夠滿足回傳的條件,就不會再繼續執行或評估第二個運算元——這樣的機制也被稱為「Short-circuit」。

即便如此,在特定場景中使用以上兩個邏輯運算子來使用 Short-circuit 的機制時,仍會遇到一些問題。因此,在 ECMAScript 2020 中推出了新的邏輯運算子:「空值合併運算符 Nullish Coalescing Operator」。

本篇將透過使用 Logical OR 介紹 Short-circuit 的運作機制和過往使用上會遇到的問題,緊接著介紹「空值合併運算符 Nullish Coalescing Operator」,以及如何適時的使用它,來解決過往的問題,並降低程式碼出錯的可能性。

Ligical OR(||)

Short-circuit 的機制不時會被用來取代 if…else… 的程式碼,而 Logical OR(||)是其中一個時常被使用的邏輯運算子。

舉下面範例來說,透過 Order() 函式能建立一筆筆訂單實例(instance),為了避免沒有帶入訂單資訊的情況,在函式內能透過 Logical OR 給定預設值——一旦第一個運算元回傳「Falsy」值,就會執行第二個運算元,藉以給定「預設值」。

下例在呼叫 Order() 函式時,由於未帶入第二個參數 size,因此 size 值為 undefined,而 undefined 為一個 Falsy 值,Logical OR 最終因而回傳第二個運算元:預設值 Medium

[embed]

以往需要以 if…else…三元運算子(Ternary Operator)的寫法,現在能透過 Logical OR 更簡潔的達成:

[embed]

❗️Falsy 值
JavaScript 當中的 Falsy 值包含 false, 0, -0, 空值 "", null, undefined, NaN 等。
在任何需要判斷 Boolean 值的上下文中(例如 if 或 while loop 等)帶入,將被轉成 false。

Ligical OR(||) 遇到的問題

Logical OR 看似好用,但也因為運作方式是「只要判定第一個運算元為 Falsy 值」就回傳後者(第二個運算元)。然而 Falsy 值的選項不只 nullundefined,還包含其他如 0 和空字串 “” 等,因此在某些情境下,誤使用 Logical OR 未必能發揮他的優勢,還反而造成反效果。

以下面範例來說,如果我們希望在使用者未選定是否要附袋子(isNeedBag)時,預設選擇要附上(true)、且如果使用者未輸入要多少糖包(sugarNum)時,預設都給予一包(1)。

[embed]

然而在執行後能發現,無論 isNeedBag 被帶入什麼布林值,都會回傳 true;而由於 0 也是 Falsy 值,因此當使用者指定不需要糖包時,Logical OR 在判定後,仍會回傳預設值 1 包 — 這與原本預期的結果不同。

在這種情況下,工程師就需要再想其他方法來解決這個問題,例如把 isNeedBag 給定預設值的寫法改成下面的方式。然而,很多時候,反而會降低程式碼的可讀性,或變得不再簡潔了。

this.isNeedBag = arg.isNeedBag !== false;

這也是為什麼在 ECMA 2020 介紹了 Nullish coalescing operator (??)。

空值合併運算符 Nullish coalescing operator (??)

空值合併運算符(Nullish coalescing operator)和 Logical OR 的功能非常相似,但相比之下更為嚴謹:與其單純判斷是否為「Falsy」值,空值合併運算符判定是否為「Nullish」值——因此唯有當第一個運算元為「undefined」或「null」時,才會回傳第二個運算元。

[embed]

如此一來,可以真實反映目標值是否未被給定或明確被給定為 undefinednull

回頭改寫訂單的範例,由於布林值 false 和數值 0 都不算 Nullish 值,因此 firstOrder.isNeedBagfirstOrder.sugarNum 在改寫後都能得到正確的回傳值。而由於訂單商品我們仍希望保有空字串的判斷,所以我們還是能繼續使用 Logical OR,因此 firstOrder.item 最終被給予預設值 Tea

[embed]

使用上的注意事項

在 JavaScirpt 中有各種運算子(Operator),而理論上要在一個運算式(Expression)使用多個運算子是沒有問題的。然而,當一個運算式中包含了多個運算子時,就會遇到「哪個運算子該先被執行」。

這其實就跟以下呈現的加減乘除一樣,由於我們人類知道「先乘除後加減」的規則,因此我們會先執行 3 * 2,再將結果 6 拿去執行 6 + 1,最終獲得 7。然而,電腦沒有這方面的知識,因此如果照著由左至右一一執行,最終將得到 8 這個答案:

1 + 3 * 2 // 7

運算子優先序(Operator precedence)

JavaScript 將運算子歸類成不同的位階,以此來決定執行的順序:運算子優先序。從位階表中能發現乘除法比加減法位階來得高,因此電腦在這方面的計算也能得出正確的答案。

邏輯運算子中 Logical AND (&&)的位階則高於 Logical OR(||),因此當一個運算式中(如下範例)同時運用了 Logical AND 和 LogicalOR,前者將優先被執行。然而,如果希望範例中的 Ligical OR 先被執行,則可以使用位階更高的 GroupingOperator () 來達成效果。

false && false || true // true
false && (false || true) // false

空值合併運算符(Nullish Coalescing Operator)的位階和 Logical OR 相同,但比 Logical AND 還來得低。若將空值運算符與另外兩個運算符「直接串接在一起合併使用」非常容易出現預期外的結果,因此是「不被允許」的,你會看到語法錯誤的訊息:

false || undefined ?? "default value"; // Uncaught Syntax Error:Unexpected token '??'

相反的,使用上開發者必須使用括號 () 明確的指定優先序:

(false || undefined) ?? :"default value"; // 'default value'
(undefined && (false || true)) ?? "default value"; // 'default value'
((undefined && false) || true) ?? "default value"; // true

結論

過往在使用 Logical OR 和 Logical AND 實作 Short Circuit 機制時,其實已經相當方便,但在一些場景下,非常容易出錯,或是讓程式碼在判斷情境時更為麻煩。空值合併運算符(Nullish Coalescing Operator)將 Logical OR 在判定運算元(Operand )的條件限縮,讓我們在實作 Short Circuit 機制上更為方便。

然而,使用上搭配 Logical OR 或 Logical AND 時,必須考量到運算子優先序的問題,因此必須透過括號明確去表明哪個運算子的位階較高,指名要先被執行——這其實也能提升程式碼的可讀性喔!

最後,如果你喜歡這篇的分享,請不吝嗇的多點幾個 👏 給我超多鼓勵,感謝 :)

參考資源

[embed]Nullish coalescing operator (??) - JavaScript | MDN The nullish coalescing operator can be seen as a special case of the logical OR (||) operator. The latter returns the…developer.mozilla.org

[embed]Operator precedence - JavaScript | MDN Consider an expression describable by the representation below, where both OP1 and OP2 are fill-in-the-blanks for…developer.mozilla.org

[embed]Nullish coalescing operator '??' The nullish coalescing operator is written as two question marks ??. As it treats null and undefined similarly, we'll…javascript.info

[embed]What is the nullish coalescing operator (??) in JavaScript? The nullish coalescing operator (??) returns the right-side value when its left-side value is null or undefined…www.educative.io

[embed]Logical OR (||) - JavaScript | MDN The logical OR (||) (logical disjunction) operator for a set of operands is true if and only if one or more of its…developer.mozilla.org


메타데이터
post_id
19d37befcf5e
slug
筆記-es2020-空值合併運算符-nullish-coalescing-operator-19d37befcf5e
url
https://medium.com/%E9%BA%A5%E5%85%8B%E7%9A%84%E5%8D%8A%E8%B7%AF%E5%87%BA%E5%AE%B6%E7%AD%86%E8%A8%98/%E7%AD%86%E8%A8%98-es2020-%E7%A9%BA%E5%80%BC%E5%90%88%E4%BD%B5%E9%81%8B%E7%AE%97%E7%AC%A6-nullish-coalescing-operator-19d37befcf5e
canonical_url
https://medium.com/%E9%BA%A5%E5%85%8B%E7%9A%84%E5%8D%8A%E8%B7%AF%E5%87%BA%E5%AE%B6%E7%AD%86%E8%A8%98/%E7%AD%86%E8%A8%98-es2020-%E7%A9%BA%E5%80%BC%E5%90%88%E4%BD%B5%E9%81%8B%E7%AE%97%E7%AC%A6-nullish-coalescing-operator-19d37befcf5e
author_url
https://medium.com/@mike-huang-mikank
status
ok
fetched_at
2026-07-26 04:08:36