iT邦幫忙

2023 iThome 鐵人賽

DAY 18
0

null 和 undefined 代表著缺少值或未定義的狀態。儘管它們在 JavaScript 中也存在,但在 TypeScript 中,可以使用靜態型別檢查來更好地處理這兩個值,以減少潛在的錯誤。

首先,讓我們簡單地了解一下 null 和 undefined 的定義:

  • null: 通常表示 變數的值為空值
  • undefined: 通常表示 變數尚未賦值,或者該值不存在。如果一個變數被聲明但未賦值,則它的值就是 undefined。
null undefined
變數的值為空 (缺少值) 變數的值尚未初始化或該值不存在
可以賦值給變數 變數聲明後但未賦值時的預設值

以下範例:

// null 可以賦值給變數,且它是一個具體的值,表示這變數已經被賦予了空值。

let a: null = null;
let b: string | null = null; 
// undefined 通常是變數聲明後但未賦值時的默認值,或者表示變數訪問的屬性或索引不存在時的值。

let a: undefined = undefined;
let b: number; // b 的默認值為 undefined
let c: string | undefined = undefined;

所以如果可以的話,通常建議盡量 為變數賦予初始值使用聯合類型、類型斷言、空值合併運算子 (??) 等來明確表示變數的可能值,以避免出現潛在的錯誤。

例如:

// 使用斷言

let str: string | null = null;
let strLength: number = (str as unknown as string).length;
// 使用空值合併運算子 (??)

let str: string | null = null;
let result = str ?? "我是威爾豬";

console.log(result); // 輸出: 我是威爾豬

null 使用情境

  • 初始化變數

    我們可以將變數初始化為 null,以表示它的值尚未被賦值或尚未確定。

let myName: string | null = null;
  • 作為函式的返回值

    有時候,函式需要返回一個值或者表示失敗的情況。

interface IUser {
  id: number;
  name: string;
}

const userData: IUser[] = [
  { id: 1, name: "威爾豬" },
  { id: 2, name: "威爾羊" },
];

function findUser(id: number): string | null {
  const user = userData.filter((item) => item.id === id);
  return user ? user[0].name : null;
}

console.log(findUser(1)); // 輸出: null
  • 清除變數的值
    我們可以將變數的值設置為 null 來清除它的內容,使其成為空值。
let data: string | null = "威爾豬";
data = null; // 清除變數的值
  • 與聯合類型一起使用
    null 可以與其他類型一起使用,以表示變數可以是多種類型之一或 null。這在處理可能缺少值的情況時很有用。

假設我們要寫一個除法函式,該函式應該要返回一個數字,但在某些情況下,數字會無法計算:

const divide = (a: number, b: number): number | null =>
  b === 0 ? null : a / b;

let result1: number | null = divide(3, 2) || null;
let result2: number | null = divide(3, 0) || null;

console.log(result1); // 輸出: 1.5
console.log(result2); // 輸出: null

undefined 使用情境

  • 初始化變數

    當您聲明一個變數但尚未為它賦值時,它的值默認為 undefined。

let a: number; // 輸出: undefined,因為變數 a 尚未被賦值
  • 函式的參數

    當函式聲明的參數未提供值時,它的值為 undefined。

function greet(name: string): void {
  console.log(`哈囉,${name}!`);
}

greet(); // 輸出: 哈囉,undefined!,因為未提供 name 參數的值
  • 函式返回值

    函式如果沒有明確指定返回值,默認返回 undefined。

function handleNothing(): void {}
console.log(handleNothing()); // 輸出: undefined
  • 處理不存在的元素或屬性
    當我們嘗試訪問陣列或物件中不存在的元素或屬性時,它們的值將為 undefined。
const mobile = ["Apple", "Samsung", "Mi"];
console.log(mobile[3]); // 輸出: undefined,因為 mobile 陣列中不存在索引值為 3 的元素
const user = { name: "威爾豬" };
console.log(user.age); // 輸出: undefined,因為 user 物件中不存在 age 屬性

使用 null 和 undefined 注意事項:

  • 避免非必要的賦值為 null 或 undefined:

  • 使用嚴格的比較運算子 (===!==):

let myName: string | undefined;

if (myName === undefined) myName = "威爾豬";
console.log(myName); // 輸出: 威爾豬
  • 檢查值的存在性 (??),並適當的提供預設值:
const getName = (name?: string): string => name ?? `不認識`; // 避免 undefined

console.log(getName()); // 輸出: 不認識
console.log(getName("威爾豬")); // 輸出: 威爾豬
const getFullName = (
  firstName: string,
  lastName: string | undefined
): string => {
  const useLastName = lastName ?? ""; // 避免 undefined

  return `${firstName} ${useLastName}`;
};

console.log(getFullName("威爾", "豬")); // 顯示: 威爾豬
console.log(getFullName("威爾", undefined)); // 顯示: 威爾
  • 函式參數使用可選串連 (?):

    參數為 null 或 undefined 時,使用可選串連會返回 undefined,不會引發錯誤警告。

https://ithelp.ithome.com.tw/upload/images/20230918/20141250oWkLW2xyze.png

const message = (message?: string | undefined): void => {
  console.log(message);
};

message("哈囉,威爾豬!"); // 顯示: 哈囉,威爾豬!
message(); // 顯示: undefined
  • 謹慎處理函式返回值:
const fetchUser = (id?: number | undefined): string | null => {
  return id !== undefined ? `威爾豬 ${id} 號` : null;
};

console.log(fetchUser()); // 輸出: null
console.log(fetchUser(1)); // 輸出: 威爾豬 1 號
console.log(fetchUser(2)); // 輸出: 威爾豬 2 號
  • 啟用嚴格的 null 檢查模式:
// tsconfig.json

{
  // ... ,
  "strictNullChecks": true,
  // ... ,
}

如果我們已經開啟了嚴格檢查模式 "strict": true ( 這個配置是嚴格模式的最高權限 ),所以 strictNullChecks 配置就可以不用再開啟了。


整體而言,null 和 undefined 可以使用它們來聲明變數的類型或處理可能缺少值的情況,但通常情況下,null 是開發者自行賦予變數的值,而 undefined 是變數默認的未賦值狀態。所以正確了解 null 和 undefined 的區別,並謹慎使用它們,才能減少潛在的錯誤和不確定性,提高程式碼的可靠性和可維護性。


上一篇
void VS. never
下一篇
非同步處理 Ⅰ (Promise)
系列文
用不到 30 天學會基本 TypeScript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言