淺析JavaScript中如何正確判斷null和undefined
相信寫(xiě)前端開(kāi)發(fā)的朋友對(duì)下面這種報(bào)錯(cuò)應(yīng)該很熟悉:
Cannot read properties of undefined
有一次我加班處理問(wèn)題,也是因?yàn)檫@一個(gè)bug。
后來(lái)才發(fā)現(xiàn),原來(lái)是一個(gè)接口返回的數(shù)據(jù)里,某個(gè)字段有時(shí)候是null導(dǎo)致的,而我沒(méi)有做判斷就直接使用了。
一、為什么需要判斷空值?
舉例如下:
// 場(chǎng)景1:用戶(hù)沒(méi)填姓名 const userName = undefined; console.log(userName.length); // 報(bào)錯(cuò)!Cannot read properties of undefined // 場(chǎng)景2:接口返回空數(shù)據(jù) const apiResponse = null; console.log(apiResponse.data); // 報(bào)錯(cuò)!Cannot read properties of null
所以,空值判斷是保證代碼健壯性的重要環(huán)節(jié)。
二、先搞懂:null 和 undefined 有啥區(qū)別?
雖然它們都表示空,但含義不同:
undefined:變量被聲明了,但還沒(méi)賦值。
let name; console.log(name); // undefined
null:程序員主動(dòng)賦值為空,表示我明確知道這里沒(méi)有值。
let user = null; // 表示“用戶(hù)不存在”
所以,當(dāng)我們說(shuō)判斷變量是否為空,通常是指:它是不是 null 或 undefined。
三、判斷方法
以下介紹了比較常用的幾種判斷方案。
方法一:顯式比較(最保險(xiǎn))
if (variable === null || variable === undefined) {
console.log('變量為空');
}
適用場(chǎng)景:
- 需要明確區(qū)分null和undefined時(shí)
- 團(tuán)隊(duì)代碼規(guī)范要求嚴(yán)格相等判斷
- 對(duì)代碼可讀性要求高的項(xiàng)目
案例:
function getUserProfile(user) {
if (user === null || user === undefined) {
return '用戶(hù)不存在';
}
return `歡迎,${user.name}`;
}
方法二:非嚴(yán)格相等(最常用)
if (variable == null) {
console.log('變量為空');
}
這里有個(gè)重要知識(shí)點(diǎn):== null 實(shí)際上等價(jià)于 === null || === undefined,這是JavaScript的語(yǔ)言特性。
為什么推薦這個(gè)寫(xiě)法?
- 代碼簡(jiǎn)潔,少寫(xiě)很多字符
- 性能優(yōu)秀,現(xiàn)代JS引擎都做了優(yōu)化
- 意圖明確,專(zhuān)業(yè)開(kāi)發(fā)者一看就懂
方法三:邏輯非操作符
if (!variable) {
console.log('變量為falsy值');
}
注意! 這個(gè)方法容易造成其它的誤傷:
// 這些值都會(huì)被判斷為"空"
!false // true
!0 // true
!"" // true
!NaN // true
// 實(shí)際開(kāi)發(fā)中的坑
const count = 0;
if (!count) {
console.log('計(jì)數(shù)為0'); // 這里會(huì)執(zhí)行,但可能不是我們想要的
}
方法四:typeof 關(guān)鍵字(安全的寫(xiě)法)
if (typeof variable === 'undefined' || variable === null) {
console.log('變量是空的!');
}
安全在哪?
// 如果變量根本沒(méi)聲明,前兩種方法會(huì)報(bào)錯(cuò)
if (notDeclaredVariable == null) { // 報(bào)錯(cuò)!ReferenceError
}
if (typeof notDeclaredVariable === 'undefined') { // 正常運(yùn)行!
console.log('變量未定義');
}
這種寫(xiě)法主要用于檢查一個(gè)變量是否被聲明過(guò),但對(duì)于普通函數(shù)參數(shù)或已聲明變量,沒(méi)必要這么復(fù)雜。
適用于不確定變量是否聲明的場(chǎng)景。
方法五:空值合并操作符(現(xiàn)代寫(xiě)法)
這是ES2020的新特性,用起來(lái)特別順手:
// 傳統(tǒng)寫(xiě)法 const name = username ? username : '匿名用戶(hù)'; // 現(xiàn)代寫(xiě)法 const name = username ?? '匿名用戶(hù)';
優(yōu)勢(shì):只對(duì) null 和 undefined 生效,不會(huì)誤判0、false等其他值。
方法六:可選鏈操作符(對(duì)象屬性專(zhuān)用)
處理嵌套對(duì)象時(shí),這個(gè)功能簡(jiǎn)直是救命稻草:
// 以前的痛苦寫(xiě)法 const street = user && user.address && user.address.street; // 現(xiàn)在的優(yōu)雅寫(xiě)法 const street = user?.address?.street;
結(jié)合空值合并,寫(xiě)法更加安全:
const street = user?.address?.street ?? '地址未知';
四、實(shí)際開(kāi)發(fā)中的建議
場(chǎng)景1:簡(jiǎn)單的空值檢查
// 推薦
if (value == null) {
// 處理空值
}
// 或者
const safeValue = value ?? defaultValue;
場(chǎng)景2:需要區(qū)分null和undefined
if (value === null) {
console.log('明確設(shè)置為空');
}
if (value === undefined) {
console.log('未定義');
}
場(chǎng)景3:處理對(duì)象屬性
// 安全訪問(wèn)深層屬性 const phone = order?.customer?.contact?.phone ?? '未填寫(xiě)';
場(chǎng)景4:函數(shù)參數(shù)默認(rèn)值
function createUser(name, age = 18) {
// age參數(shù)只在undefined時(shí)使用默認(rèn)值
return { name, age };
}
五、總結(jié)
雖然現(xiàn)代JavaScript引擎優(yōu)化得很好,但了解原理還是有幫助的:
== null和顯式比較性能相當(dāng)typeof檢查稍慢,但能安全檢測(cè)未聲明變量- 可選鏈操作符在現(xiàn)代瀏覽器中性能優(yōu)秀
| 場(chǎng)景 | 推薦寫(xiě)法 | 原因 |
|---|---|---|
| 一般空值檢查 | value == null | 簡(jiǎn)潔高效 |
| 需要明確意圖 | value === undefined | 可讀性強(qiáng) |
| 設(shè)置默認(rèn)值 | value ?? defaultValue | 安全準(zhǔn)確 |
| 對(duì)象屬性訪問(wèn) | obj?.prop | 避免報(bào)錯(cuò) |
| 函數(shù)參數(shù) | 參數(shù)默認(rèn)值 | 語(yǔ)言特性 |
沒(méi)有絕對(duì)最好的方法,只有最適合當(dāng)前場(chǎng)景的選擇。根據(jù)你的具體需求和團(tuán)隊(duì)規(guī)范來(lái)決策吧!
到此這篇關(guān)于淺析JavaScript中如何正確判斷null和undefined的文章就介紹到這了,更多相關(guān)JavaScript判斷null和undefined內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript實(shí)現(xiàn)圖像循環(huán)明暗變化的方法
這篇文章主要介紹了javascript實(shí)現(xiàn)圖像循環(huán)明暗變化的方法,實(shí)例分析了javascript操作css樣式的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-02-02
javascript實(shí)現(xiàn)textarea中tab鍵的縮排處理方法
這篇文章主要介紹了javascript實(shí)現(xiàn)textarea中tab鍵的縮排處理方法,涉及javascript處理鼠標(biāo)事件及頁(yè)面元素的相關(guān)技巧,需要的朋友可以參考下2015-06-06
js以分隔符分隔數(shù)組中的元素并轉(zhuǎn)換為字符串的方法
下面小編就為大家?guī)?lái)一篇js以分隔符分隔數(shù)組中的元素并轉(zhuǎn)換為字符串的方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-11-11
JavaScript對(duì)象和字串之間的轉(zhuǎn)換實(shí)例探討
從對(duì)象的格式可以看出,如果字串的格式定義成 json 格式的, 就可以直接轉(zhuǎn)換為obj了,感興趣的朋友可以參考下哈2013-04-04
微信小程序中如何使用xlsx(xlsx.mini.min.js)實(shí)現(xiàn)Excel導(dǎo)入導(dǎo)出功能
這篇文章主要介紹了微信小程序中如何使用xlsx(xlsx.mini.min.js)實(shí)現(xiàn)Excel導(dǎo)入導(dǎo)出功能的相關(guān)資料,包括準(zhǔn)備工作、導(dǎo)出Excel的基本流程、導(dǎo)入Excel的基本流程、常用API說(shuō)明以及注意事項(xiàng),需要的朋友可以參考下2026-01-01
javascript實(shí)現(xiàn)捕捉鍵盤(pán)上按下的鍵
JavaScript取得按下鍵盤(pán)的鍵是哪個(gè),通過(guò)創(chuàng)建一個(gè)event.keyCode對(duì)象,可有效獲取鍵盤(pán)上的鍵,運(yùn)行代碼后,點(diǎn)擊鍵盤(pán)上的任意鍵,網(wǎng)頁(yè)上顯示你按下的是哪個(gè)鍵。2015-05-05
淺談DOM的操作以及性能優(yōu)化問(wèn)題-重繪重排
下面小編就為大家?guī)?lái)一篇淺談DOM的操作以及性能優(yōu)化問(wèn)題-重繪重排。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-01-01

