在 JavaScript 中,null
、undefined
?和?NaN
?是三個特殊的「非正常值」,正確判斷它們是保證代碼健壯性的關鍵。本文結合 ECMA 規范與 MDN 權威文檔,系統梳理三者的判斷方法、原理及典型場景,幫助開發者規避常見誤區。
一、理解三個特殊值的本質
undefined
:表示「變量未初始化」或「對象屬性未顯式賦值」(如聲明變量未賦值、訪問不存在的對象屬性)。null
:表示「有意為之的空值」(通常用于表示「空對象」,如?let obj = null
)。NaN
(Not a Number):表示「非數字」,常見于數值計算失敗場景(如?0/0
、"abc" - 1
)。
二、判斷?undefined
?的權威方法
undefined
?的核心特征是「未初始化」,判斷時需注意兼容性。
1. 使用?typeof
(推薦,兼容未聲明變量)
typeof
?返回變量的類型字符串("undefined"
?表示未初始化)。即使變量未聲明,typeof
?也不會拋出錯誤,適合安全檢查。
javascript
// 變量已聲明但未初始化
let a;
console.log(typeof a === "undefined"); // true// 檢查對象不存在的屬性(安全)
const obj = { name: "張三" };
console.log(typeof obj.age === "undefined"); // true(age屬性未定義)// 變量未聲明(不會報錯)
console.log(typeof b === "undefined"); // true(b未聲明)
2. 直接比較?=== undefined
(需變量已聲明)
若變量已聲明,可通過嚴格等于?undefined
?判斷,但未聲明變量會拋出?ReferenceError
。
javascript
let c;
console.log(c === undefined); // true(變量已聲明未初始化)// 未聲明變量直接比較會報錯!
// console.log(d === undefined); // Uncaught ReferenceError: d is not defined
三、判斷?null
?的權威方法
null
?是「主動設置的空對象」,需嚴格區分于其他值。
唯一可靠方式:=== null
typeof null
?會返回?"object"
(歷史遺留問題),因此必須通過嚴格等于?null
?判斷。
javascript
const obj = null;
console.log(obj === null); // true(正確判斷null)// 錯誤示例:typeof無法區分null和對象
console.log(typeof null); // "object"(無法用typeof判斷null)
四、判斷?NaN
?的權威方法
NaN
?是唯一不滿足?x === x
?的值(NaN !== NaN
),判斷需結合其特性。
1. ES6 新增?Number.isNaN
(嚴格判斷,推薦)
僅當值本身是?NaN
?時返回?true
,不會隱式轉換其他類型。
javascript
console.log(Number.isNaN(NaN)); // true(直接判斷NaN)
console.log(Number.isNaN("abc" - 1)); // true(計算結果為NaN)
console.log(Number.isNaN("123")); // false(字符串不是NaN)
2. 傳統?isNaN
(非嚴格,需謹慎)
先將參數隱式轉換為數字,再判斷是否為?NaN
,可能誤判其他類型。
javascript
console.log(isNaN(NaN)); // true(正確)
console.log(isNaN("abc")); // true("abc"轉數字為NaN)
console.log(isNaN("123")); // false("123"轉數字為123)
3. 利用?NaN !== NaN
?特性(兼容舊環境)
NaN
?是唯一不滿足自身相等的值,可手動實現判斷函數。
javascript
function isNaNPolyfill(value) {return value !== value;
}
console.log(isNaNPolyfill(NaN)); // true
console.log(isNaNPolyfill("abc" - 1)); // true(結果為NaN)
五、綜合場景與補充方法
實際開發中,需根據需求靈活組合判斷邏輯。
場景 1:統一判斷?null
?或?undefined
利用寬松相等(null == undefined
?為?true
),快速判斷兩者。
javascript
const value = null;
if (value == null) { // 等價于 value == undefinedconsole.log("值為null或undefined"); // 觸發
}
場景 2:函數參數默認值處理(ES6 解構賦值)
解構賦值的默認值僅在參數為?null
?或?undefined
?時生效,其他假值(如?0
)不觸發。
javascript
function getUserInfo({ age = "未知" } = {}) { console.log(`年齡:${age}`);
}getUserInfo({ age: null }); // 輸出 "年齡:未知"(null觸發默認值)
getUserInfo({ age: 0 }); // 輸出 "年齡:0"(0是有效值,不觸發默認值)
場景 3:使用工具庫(如 Lodash)
成熟工具庫提供語義化方法,提升代碼可讀性。
javascript
import { isNil, isNull, isUndefined } from "lodash";isNull(null); // true(僅判斷null)
isUndefined(undefined); // true(僅判斷undefined)
isNil(null); // true(判斷null或undefined)
isNil(undefined); // true
六、總結與最佳實踐
值 | 權威判斷方法 | 適用場景 |
---|---|---|
undefined | typeof value === "undefined" | 安全檢查未聲明變量或對象屬性 |
null | value === null | 明確判斷「主動設置的空對象」 |
NaN | Number.isNaN(value) (ES6) | 嚴格判斷非數字結果 |
綜合判斷 | value == null (null/undefined)lodash.isNil (工具庫) | 無需區分 null 和 undefined 時快速過濾 |
參考規范:
- ECMA-262 規范:typeof、Null、NaN。
- MDN 文檔:undefined、null、NaN。