全面解析JavaScript 中 null
JavaScript 有兩種類(lèi)型:原始類(lèi)型(strings, booleans, numbers, symbols)和對(duì)象
對(duì)象是一個(gè)復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。最簡(jiǎn)單的 JavaScript 對(duì)象是普通對(duì)象 —— 鍵和相關(guān)值的集合
let myObject = {
name: 'Eric Cartman'
};但是很多情況下不能創(chuàng)建一個(gè)對(duì)象。在這種情況下,JavaScript 提供了一個(gè)特殊的值 null —— 表示缺少對(duì)象
let myObject = null;
在這篇文章中,你將學(xué)習(xí)關(guān)于 JavaScript 中的 null 的一切: 它的含義,如何檢測(cè)它,null 和 undefined 之間的區(qū)別,以及為什么大量使用 null 會(huì)造成代碼維護(hù)困難等
1.null 的概念
JavaScript 規(guī)范中這么描述 null
null 是一種原始類(lèi)型,表示有意不包含任何對(duì)象值
如果您看到 null(分配給變量或由函數(shù)返回),那么在那個(gè)位置原本應(yīng)該是一個(gè)對(duì)象,但由于某種原因,一個(gè)對(duì)象沒(méi)有創(chuàng)建
比如,函數(shù) greetObject() 創(chuàng)建對(duì)象,但也可以在無(wú)法創(chuàng)建對(duì)象時(shí)返回 null:
function greetObject(who) {
if (!who) {
return null;
}
return { message: `Hello, ${who}!` };
}
greetObject('Eric'); // => { message: 'Hello, Eric!' }
greetObject(); // => null當(dāng)上面的函數(shù)中傳入一個(gè)字符串參數(shù)時(shí),如預(yù)期的,函數(shù)返回一個(gè)對(duì)象 { message: 'Hello, Eric!' }
但是,函數(shù)中不傳任何參數(shù)時(shí),該函數(shù)返回 null。返回 null 是合理的,因?yàn)?who 參數(shù)沒(méi)有值,導(dǎo)致 greeting 對(duì)象無(wú)法創(chuàng)建
1.1 null 的一個(gè)比較貼切的比喻
考慮關(guān)于 null 的一個(gè)比較貼切的比喻,你可以把變量想象成一個(gè)盒子。就像變量可以容納對(duì)象一樣,盒子也可以容納像茶壺等的物品
但一旦你收到一個(gè)盒子,打開(kāi)它,什么也沒(méi)有!有人弄錯(cuò)了,給了你一個(gè)空盒子。該盒子不包含任何內(nèi)容,或者換句話說(shuō),它包含一個(gè) null 值
2. 如何去檢測(cè) null
檢查 null 好方法是使用嚴(yán)格相等運(yùn)算符
const missingObject = null;
const existingObject = { message: 'Hello!' };
missingObject === null; // => true
existingObject === null; // => falsemissingObject === null 的結(jié)果為 true,因?yàn)?missingObject 變量包含一個(gè) null 值。如果變量包含非空值,比如對(duì)象,則表達(dá)式 existingObject === null 的結(jié)果為 false
2.1 null 是一個(gè)假值
null 與 false、0、"、undefined、NaN 都是假值。如果在條件語(yǔ)句中遇到它們,那么 JavaScript 將把它們強(qiáng)制為 false
Boolean(null); // => false
if (null) {
console.log('null is truthy');
} else {
console.log('null is falsy'); // logs 'null is falsy'
}2.2 typeof null
typeof value 類(lèi)型操作符可以確定值的類(lèi)型。例如,類(lèi)型為 15 的是 number,typeof { prop: 'Value' } 等于 object。
有趣的是,null 值類(lèi)型的結(jié)果是什么
typeof null; // => 'object'
一個(gè)缺失的對(duì)象類(lèi)型怎么被判斷為 object? 原來(lái) typoef null 作為 object 是早期 JavaScript 實(shí)現(xiàn)中的一個(gè)錯(cuò)誤
不要使用 typeof 操作符檢測(cè) null 值。如前所述,使用嚴(yán)格的相等運(yùn)算符 myVar === null
如果你想使用 typeof 去檢查一個(gè)變量是否是一個(gè)對(duì)象,你必須排除掉 null 的情況
function isObject(object) {
return typeof object === 'object' && object !== null;
}
isObject({ prop: 'Value' }); // => true
isObject(15); // => false
isObject(null); // => false3. null 的陷阱
null 通常會(huì)在你希望使用對(duì)象的情況下意外出現(xiàn)。然后,如果嘗試從 null 中提取屬性,JavaScript 會(huì)拋出一個(gè)錯(cuò)誤
讓我們?cè)俅问褂?greetObject() 函數(shù)并嘗試從返回的對(duì)象中訪問(wèn) message 屬性
let who = ''; greetObject(who).message; // throws "TypeError: greetObject() is null"
因?yàn)?who 變量是一個(gè)空字符串,所以函數(shù)返回 null。當(dāng)從 null 訪問(wèn) message 屬性時(shí),將拋出類(lèi)型錯(cuò)誤錯(cuò)誤
你可以通過(guò)使用 可選鏈操作符 來(lái)處理 null
let who = ''; greetObject(who)?.message ?? 'Hello, Stranger!'; // => 'Hello, Stranger!'
或者使用下一節(jié)中描述的兩種選擇。
4. null 的替代方案
當(dāng)你不能構(gòu)造一個(gè)對(duì)象時(shí),很容易返回 null。但這種做法也有缺點(diǎn)
一旦 null 出現(xiàn)在執(zhí)行堆棧中,你總是必須檢查它
我們盡量避免返回 null:
- 返回默認(rèn)對(duì)象而不是
null - 拋出錯(cuò)誤而不是返回
null
讓我們回憶一下 greetObject() 函數(shù)返回 greeting 對(duì)象
當(dāng)缺少參數(shù)時(shí),可以返回一個(gè)默認(rèn)對(duì)象,而不是返回 null
function greetObject(who) {
if (!who) {
who = 'Stranger';
}
return { message: `Hello, ${who}!` };
}
greetObject('Eric'); // => { message: 'Hello, Eric!' }
greetObject(); // => { message: 'Hello, Stranger!' }或者拋出一個(gè)錯(cuò)誤
function greetObject(who) {
if (!who) {
throw new Error('"who" argument is missing');
}
return { message: `Hello, ${who}!` };
}
greetObject('Eric'); // => { message: 'Hello, Eric!' }
greetObject(); // => throws an error這些實(shí)踐可以讓你完全避免處理 null
5. null vs undefined
undefined 就是未初始化的變量或?qū)ο髮傩缘闹?/p>
例如,如果在聲明變量時(shí)沒(méi)有賦初值,那么訪問(wèn)該變量的結(jié)果為 undefined
let myVariable; myVariable; // => undefined
null 和 undefined 之間的主要區(qū)別是,null 表示丟失了的對(duì)象,而 undefined 表示未初始化的狀態(tài)
嚴(yán)格相等運(yùn)算符 === 區(qū)分 null 和 undefined
null === undefined; // => false
而松散相等運(yùn)算符 == 則認(rèn)為 null 和 undefined 相等
null == undefined; // => true
我使用松散相等運(yùn)算符檢查變量是否為 null 或 undefined
function isEmpty(value) {
return value == null;
}
isEmpty(42); // => false
isEmpty({ prop: 'Value' }); // => false
isEmpty(null); // => true
isEmpty(undefined); // => true6. 總結(jié)
null 是 JavaScript 中的一個(gè)特殊值,表示丟失的對(duì)象
嚴(yán)格相等運(yùn)算符判斷變量是否為空: variable === null。
typoef 操作符用于確定變量的類(lèi)型(number, string, boolean)。但是,typeof 在 null 情況下會(huì)引起誤解: typeof null 結(jié)果為 object
null 和 undefined 在某種程度上是等價(jià)的,但null 表示一個(gè)丟失的對(duì)象,而 undefined 表示未初始化狀態(tài)
盡可能避免返回 null 或?qū)⒆兞吭O(shè)置為 null。因?yàn)檫@種做法會(huì)導(dǎo)致 null 值的擴(kuò)展和需要對(duì) null 的驗(yàn)證。相反,嘗試使用具有默認(rèn)屬性的對(duì)象,或者甚至拋出錯(cuò)誤會(huì)是更好的實(shí)踐
你會(huì)使用什么方法來(lái)檢查 null?
到此這篇關(guān)于關(guān)于 JavaScript 中 null 的一切的文章就介紹到這了,更多相關(guān)JavaScript null內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
echarts圖形x、y坐標(biāo)文字設(shè)置間隔顯示及相關(guān)問(wèn)題詳解
最近在做一個(gè)web的數(shù)據(jù)統(tǒng)計(jì)部分用到了Echart,下面這篇文章主要給大家介紹了關(guān)于echarts圖形x、y坐標(biāo)文字設(shè)置間隔顯示及相關(guān)問(wèn)題的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08
Javascript實(shí)現(xiàn)的類(lèi)似Google的Div拖動(dòng)效果代碼
Javascript實(shí)現(xiàn)的類(lèi)似Google的Div拖動(dòng)效果代碼,需要的朋友可以參考下。2011-08-08
JavaScript實(shí)現(xiàn)圖片懶加載的三種方案詳解
圖片懶加載,當(dāng)圖片出現(xiàn)在可視區(qū)域再進(jìn)行加載,提升用戶的體驗(yàn),這篇文章主要為大家整理了三個(gè)常用的圖片懶加載實(shí)現(xiàn)方法,希望對(duì)大家有所幫助2023-12-12
JavaScript實(shí)現(xiàn)單點(diǎn)登錄的示例
這篇文章主要介紹了JavaScript實(shí)現(xiàn)單點(diǎn)登錄的示例,幫助大家更好的理解和使用JavaScript,感興趣的朋友可以了解下2020-09-09
小程序瀑布流組件實(shí)現(xiàn)翻頁(yè)與圖片懶加載
這篇文章主要介紹了小程序瀑布流組件實(shí)現(xiàn)翻頁(yè)與圖片懶加載,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05
JavaScript時(shí)間操作之年月日星期級(jí)聯(lián)操作
這篇文章主要介紹了JavaScript時(shí)間操作之級(jí)聯(lián)日期選擇操作,涉及到年、月、日、星期,感興趣的小伙伴們可以參考一下2016-01-01
javascript實(shí)現(xiàn)全角轉(zhuǎn)半角的方法
這篇文章主要介紹了javascript實(shí)現(xiàn)全角轉(zhuǎn)半角的方法,涉及JavaScript字符串遍歷與編碼轉(zhuǎn)換的相關(guān)技巧,需要的朋友可以參考下2016-01-01

