1. 程式人生 > 程式設計 >ES2020系列之空值合併運算子 '??'

ES2020系列之空值合併運算子 '??'

空值合併運算子 ?? 提供了一種簡短的語法,用來獲取列表中第一個“已定義”的變數(譯註:即值不是 null 或 undefined 的變數)。

a ?? b 的結果是:

  • a,如果 a 不是 null 或 undefined,
  • b,其他情況。

所以,x = a ?? b 是下面這個表示式的簡寫:

x = (a !== null && a !== undefined) ? a : b;

下面是一個更長一點的例子。

假設,我們有一個使用者,變數 firstName、lastName 和 nickName 分別對應使用者的名字、姓氏和暱稱。如果使用者決定不輸入任何值,那麼這些變數都可能是未定義的。

我們想要顯示使用者的名稱:顯示這三個變數中的一個,如果都沒有設定值,則顯示 "Anonymous"。
讓我們使用 ?? 運算子選擇第一個已定義的變數:

let firstName = null;
let lastName = null;
let nickName = "Supercoder";

// 顯示第一個不是 null/undefined 的值
alert(firstName ?? lastName ?? nickName ?? "Anonymous"); // Supercoder

與 || 比較

或運算子 || 可以與 ?? 運算子以同樣的方式使用。正如 上一章 所講的,我們可以用 || 替換上面示例中的 ??,也可以獲得相同的結果。

重要的區別是:

  • || 返回第一個 真 值。
  • ?? 返回第一個 已定義的 值。

當我們想將 null/undefined 與 0 區別對待時,這個區別至關重要。

例如,考慮下面這種情況:

height = height ?? 100;

如果 height 未定義,則將其賦值為 100。

讓我們將其與 || 進行比較:

let height = 0;

alert(height || 100); // 100
alert(height ?? 100); // 0

在這個例子中,height || 100 將值為 0 的 height 視為未設定的(unset),與 null、undefined 以及任何其他假(falsy)值同等對待。因此得到的結果是 100。

height ?? 100 僅當 height 確實是 null 或 undefined 時才返回 100。因此,alert 按原樣顯示了 height 值 0。

哪種行為更好取決於特定的使用場景。當高度 0 為有效值時,?? 運算子更適合。

優先順序

?? 運算子的優先順序相當低:在 MDN table 中為 5。

因此,?? 在大多數其他運算之後,但在 = 和 ? 之前進行運算。

如果我們需要在複雜表示式中使用 ?? 進行取值,需要考慮加括號:

let height = null;
let width = null;

// 重要:使用括號
let area = (height ?? 100) * (width ?? 50);

alert(area); // 5000

否則,如果我們省略了括號,* 的優先順序比 ?? 高,會優先執行。

運算過程將等同於下面這個表示式:

// 可能不正確的
let area = height ?? (100 * width) ?? 50;

這裡還有一個相關的語言級別的限制。

出於安全原因,禁止將 ?? 運算子與 && 和 || 運算子一起使用。

下面的程式碼會觸發一個語法錯誤:

let x = 1 && 2 ?? 3; // Syntax error

這個限制無疑是值得商榷的,但是它被新增到語言規範中是為了避免程式設計錯誤,因為人們開始使用 ?? 替代 ||。

可以明確地使用括號來解決這個問題:

let x = (1 && 2) ?? 3; // 起作用

alert(x); // 2

總結

空值合併運算子 ?? 提供了一種簡潔的方式獲取列表中“已定義”的值。

它被用於為變數分配預設值:

// 當 height 的值為 null 或 undefined 時,將 height 的值設定為 100
height = height ?? 100;

?? 運算子的優先順序非常低,只略高於 ? 和 =。

如果沒有明確新增括號,不能將其與 || 或 && 一起使用。

到此這篇關於ES2020系列之空值合併運算子 '??'的文章就介紹到這了,更多相關ES2020 空值合併運算子 內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!