軌道
/
JavaScript
JavaScript
/
課程大綱
/
Null 與 Undefined
Nu

Null 與 Undefined 在 JavaScript

1 個練習

關於 Null 與 Undefined

與許多其他語言不同,JavaScript 裡有兩種不同的東西,用來代表缺少(有意義的)值。 它們就是 null 和 undefined。

Null

原始值 null 用來表示變數刻意設定成的「空值」。 在其他語言裡,類似的結構可能只用於(缺少的)物件或指標型別。 在 JavaScript 中,null 通常代表任何型別的空值。

let name = null;
// name is intentionally set to "empty" because it is not
// available

你可以用嚴格相等運算子===檢查變數是否為 null。 雖然 null 是原始值,但出於歷史因素,typeof 運算子會「錯誤地」回傳 object。 這表示不能單靠它來檢查變數是否為 null。

let name = null;

name === null;
// => true

// Pitfall:
typeof name;
// => 'object'

Undefined

尚未被指定值的變數,型別為 undefined。1

這表示 null 代表空值(但仍然是個值),而 undefined 代表完全沒有值。🤯

undefined 會出現在各種不同的情境中。

  • 如果變數在宣告時沒有給值(初始化),它就是 undefined。
  • 如果你試著存取物件裡不存在的鍵,會得到 undefined。
  • 如果函式沒有回傳值,結果就是 undefined。
  • 如果呼叫函式時沒有傳入引數,該引數就是 undefined,除非它有預設值。
let name;
console.log(name);
// => undefined

let obj = { greeting: 'hello world' };
console.log(obj.missingKey);
// => undefined

function returnNothing() {
  return;
}
console.log(returnNothing());
// => undefined

你可以用嚴格相等運算子===或typeof運算子來檢查變數是否為 undefined。

let name;

name === undefined;
// => true

typeof name === 'undefined';
// => true

不建議手動把 undefined 指定給變數,請改成一律使用 null,清楚表達你是刻意設定空值。

選擇性鏈結

如前面提到的,在 JavaScript 中存取物件裡不存在的鍵會回傳 undefined。 不過,如果你試著取得巢狀的值,而父層的鍵不存在,就會對 undefined 取值,導致 TypeError: Cannot read property ... of undefined。 理論上,你總是需要先檢查父層的鍵存在,才能試著取得巢狀的鍵。 以往這通常用 AND 運算子&&來做,但對於深層巢狀的值,這會產生非常冗長的運算式。

obj.level1 && obj.level1.level2 && obj.level1.level2.level3;

為了解決這個問題,語言規格在 2020 年加入了選擇性鏈結。 有了選擇性鏈結運算子?.,你可以確保 JavaScript 只在父層不是 null 或 undefined 時,才嘗試存取巢狀的鍵。 否則就會回傳 undefined。

const obj = {
  address: {
    street: 'Trincomalee Highway',
    city: 'Batticaloa',
  },
};

obj.residence;
// => undefined

obj.address.zipCode;
// => undefined

obj.residence.street;
// => TypeError: Cannot read property 'street' of undefined

obj.residence?.street;
// => undefined

obj.residence?.street?.number;
// => undefined

空值合併

有些情況下,你會想在變數為 null 或 undefined 時套用預設值。 以前這通常用三元運算子?來做,或利用 OR 運算子||的惰性求值。 這有個缺點:只要變數是 falsy(例如 '' 或 0),預設值就會被套用,而不只在它是 null 或 undefined 的時候。 這很容易造成意料之外的結果。

let amount = null;
amount = amount || 1;
// => 1

amount = 0;
amount = amount || 1;
// => 1

amount = 0;
amount ? amount : 1;
// => 1

為了處理這點,空值合併運算子??被引進。 就像選擇性鏈結一樣,它也在 2020 年被加入語言規格。 空值合併運算子??只有在左邊的運算元是 null 或 undefined 時,才會回傳右邊的運算元。 否則就回傳左邊的運算元。 這樣一來,就能更精確地套用預設值。

let amount = null;
amount = amount ?? 1;
// => 1

amount = 0;
amount = amount ?? 1;
// => 0

[1] Undefined, MDN. (2021). https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined (2021 年 6 月 4 日存取)。

透過 GitHub 編輯 連結會在新視窗或分頁中開啟

學習 Null 與 Undefined