TypeScript - null 與 undefined 的差異
Hello, 有志者們!今天,我們將深入一個常讓初學者感到困惑的興奮主題:TypeScript 中 null
與 undefined
的差異。別擔心如果你覺得有點不知所措 – 我記得我第一次遇到這些概念時,我也曾經抓破頭!但到了這堂課的結束,你將會專業地區分這兩個特殊值。我們開始吧!
null 是什麼?
在 TypeScript(和 JavaScript)中,null
是一個特殊的值,代表故意沒有任何對象值。這就像在說,「嘿,這裡應該有東西,但現在,什麼都沒有。」
讓我們看一些例子來更好地理解這個概念:
let myPet: string | null = null;
console.log(myPet); // 輸出:null
// 代碼稍後...
myPet = "Fluffy";
console.log(myPet); // 輸出:Fluffy
在這個例子中,我們聲明了一個可以為 string 或 null 的變量 myPet
。最初,我們將它設為 null
,表示我們還沒有寵物。稍後,當我們有寵物時,我們將名字 "Fluffy" 賦值給 myPet
。
這裡有另一個例子:
function findUser(id: number): { name: string } | null {
// 想像我們正在搜索數據庫
if (id === 1) {
return { name: "Alice" };
} else {
return null;
}
}
let user = findUser(1);
console.log(user); // 輸出:{ name: "Alice" }
user = findUser(2);
console.log(user); // 輸出:null
在這種情況下,我們的 findUser
函數返回一個用戶對象或 null
如果沒有找到用戶。這是編程中常見的模式 - 使用 null
來表示搜索或操作沒有產生結果。
undefined 是什麼?
現在,讓我們來谈谈 undefined
。這個特殊值代表一個已聲明但尚未賦值的變量。這就像一個空盒子 - 它存在,但還沒有東西。
這裡有一些例子來說明 undefined
:
let myName: string;
console.log(myName); // 輸出:undefined
// 代碼稍後...
myName = "John";
console.log(myName); // 輸出:John
function greet(name?: string) {
console.log(name);
}
greet(); // 輸出:undefined
greet("Alice"); // 輸出:Alice
在第一部分,我們聲明了 myName
但沒有賦值。TypeScript 自動給它 undefined
的值。稍後,我們賦值,它就不再是 undefined。
在 greet
函數中,我們使用了一個可選參數。如果我們在不提供參數的情況下調用函數,name
參數將會是 undefined
。
這裡有另一個你可能會遇到 undefined
的情況:
let person = {
name: "Bob",
age: 30
};
console.log(person.name); // 輸出:Bob
console.log(person.job); // 輸出:undefined
在這種情況下,person.job
是 undefined
,因為我們從未為我們的 person
對象定義過 job
屬性。
Null 與 Undefined:關鍵差異
現在我們已經分別探討了 null
和 undefined
,讓我們將它們並列比較,以更好地理解它們的差異。
方面 | null | undefined |
---|---|---|
含義 | 故意缺少任何對象值 | 變量已聲明但未賦值 |
類型 | 對象 | Undefined |
在 JSON 中 | 有效 | 無效 |
函數默認參數 | 不用作默認 | 用作可選參數的默認 |
相等性 | null == undefined (true), null === undefined (false) | undefined == null (true), undefined === null (false) |
讓我們看一些代碼例子來說明這些差異:
// 類型檢查
console.log(typeof null); // 輸出:"object"
console.log(typeof undefined); // 輸出:"undefined"
// JSON 序列化
console.log(JSON.stringify({ a: null })); // 輸出:{"a":null}
console.log(JSON.stringify({ a: undefined })); // 輸出:{}
// 函數默認參數
function sayHello(name: string = "World") {
console.log(`Hello, ${name}!`);
}
sayHello(); // 輸出:Hello, World!
sayHello(undefined); // 輸出:Hello, World!
sayHello(null); // 輸出:Hello, null!
// 相等性
console.log(null == undefined); // 輸出:true
console.log(null === undefined); // 輸出:false
實際上,在 null
和 undefined
之間的選擇通常取決於個人或團隊的偏好。然而,理解這些差異可以幫助你寫出更精確且無錯誤的代碼。
這裡有一個最後的例子來總結一切:
function processUser(user: { name: string, age?: number } | null | undefined) {
if (user === null) {
console.log("用戶顯式設為 null");
} else if (user === undefined) {
console.log("用戶未提供");
} else {
console.log(`處理用戶:${user.name}, 年齡:${user.age ?? "未知"}`);
}
}
processUser(null); // 輸出:用戶顯式設為 null
processUser(undefined); // 輸出:用戶未提供
processUser({ name: "Alice" }); // 輸出:處理用戶:Alice, 年齡:未知
processUser({ name: "Bob", age: 30 }); // 輸出:處理用戶:Bob, 年齡:30
這個函數展示了我們如何在真實世界情況中區分 null
、undefined
和有效的用戶對象。
這就是全部了!你剛剛學會了 TypeScript 中 null
和 undefined
的來龍去脈。記住,熟練來自練習,所以不要害怕在你自己的代碼中嘗試這些概念。快樂編程,願你的變量總是故意地為 null 或 undefined!
Credits: Image by storyset