一文讓你徹底弄懂js中undefined和null的區(qū)別
前言
undefined 和 null 的區(qū)別是個(gè)老生常談的話(huà)題了,之前我對(duì)二者的區(qū)別只是簡(jiǎn)單理解,例如二者轉(zhuǎn)成 Boolean 類(lèi)型都是 false、使用 == 進(jìn)行比較時(shí)為 true、使用 === 進(jìn)行比較時(shí)為 false 等,卻沒(méi)有真正系統(tǒng)地總結(jié)二者的區(qū)別。
某天,下班前幾分鐘,我徹底弄懂了 undefined 和 null 的區(qū)別。
一、基本概念
1、undefined
undefined 是“全局對(duì)象”的一個(gè)屬性。也就是說(shuō),它是全局作用域的一個(gè)變量(下面展開(kāi)對(duì) undefined 變量的賦值操作)。undefined 的最初值就是原始數(shù)據(jù)類(lèi)型 undefined。
2、null
null 是一個(gè)字面量,不像 undefined,它不是“全局對(duì)象”的一個(gè)屬性。null 是表示缺少的標(biāo)識(shí),指示變量未指向任何對(duì)象。把 null 作為尚未創(chuàng)建的對(duì)象,或許更好理解。在 API 中,null 常使用來(lái)表示返回類(lèi)型應(yīng)是一個(gè)對(duì)象,但沒(méi)有關(guān)聯(lián)某個(gè)具體對(duì)象的這么一個(gè)值。
二、簡(jiǎn)單區(qū)別
總的來(lái)說(shuō),null 和 undefined 都表示空,主要區(qū)別在于 undefined 表示尚未初始化的變量的值,而 null 表示該變量有意缺少對(duì)象指向。
undefined
- 這個(gè)變量從根本上就沒(méi)有定義。
- 隱藏式 空值。
null
- 這個(gè)值雖然定義了,但它并未指向任何內(nèi)存中的對(duì)象。
- 聲明式 空值。
以下是一張經(jīng)典的圖片,幫助我們理解。
三、表現(xiàn)形式
undefined 和 null 在 JavaScript 中有什么不同的表現(xiàn)形式,理解這些表現(xiàn)形式,可以幫助我們更好地理解 undefined 和 null 的區(qū)別。
1、typeof
console.log(typeof undefined); // 'undefined' console.log(typeof null); // 'object'
typeof null 為 object 是一個(gè)歷史遺留問(wèn)題,直到現(xiàn)階段都無(wú)法被修復(fù)。
在 JavaScript 初始版本中,值以 32位 存儲(chǔ)。前 3位 表示數(shù)據(jù)類(lèi)型的標(biāo)記,其余位則表示值。
對(duì)于所有對(duì)象類(lèi)型,它的前 3位 都以 000 作為類(lèi)型標(biāo)記位。在 JavaScript 早期版本中,null 被認(rèn)為是一個(gè)特殊的值,用來(lái)對(duì)應(yīng) C 中的空指針,但 JavaScript 中沒(méi)有 C 中的指針概念,所以 null 意味著什么都沒(méi)有或者 void 并以 全0(32位)表示。
因此每當(dāng) JavaScript 讀取 null 時(shí),它的前 3位 將它視為對(duì)象類(lèi)型,這也是為什么 typeof null 返回 object 的原因。
2、== 與 ===
console.log(null == undefined); // true console.log(null === undefined); // false console.log(!!null === !!undefined); // true
這一點(diǎn)相信大家都明白,== 比較的是值,而 === 比較的是值跟類(lèi)型。undefined 和 null 的布爾值都為 false,因此在用 == 比較時(shí),為 true;而 undefined 和 null 的類(lèi)型不同,因此在用 === 比較時(shí)為 false。
3、Object.prototype.toString.call
console.log( Object.prototype.toString.call(undefined) ); // '[object Undefined]' console.log( Object.prototype.toString.call(null) ); // '[object Null]'
toString() 是 Object 的原型方法,調(diào)用該方法,默認(rèn)返回當(dāng)前對(duì)象的 [[Class]]。這是一個(gè)內(nèi)部屬性,其格式為 [object Xxx],其中 Xxx 就是對(duì)象的類(lèi)型。
那么既然在 JavaScript 中,萬(wàn)物皆對(duì)象,為什么 xxx.toString() 不能返回變量類(lèi)型?
這是因?yàn)楦鱾€(gè)類(lèi)中重寫(xiě)了 toString(),因此需要調(diào)用 Object 中的 toString(),且必須使用 toString.call() 的方式調(diào)用。對(duì)于 Object 對(duì)象,直接調(diào)用 toString() 就能返回 [object Object];而對(duì)于其他對(duì)象,則需要通過(guò) call / apply 來(lái)調(diào)用才能返回正確的類(lèi)型信息。
4、+ 運(yùn)算 與 Number()
let a = undefined + 1; let b = null + 1; console.log(a); // NaN console.log(b); // 1 console.log(Number(undefined)); // NaN console.log(Number(null)); // 0
這涉及到 JavaScript 中的隱式類(lèi)型轉(zhuǎn)換,在執(zhí)行加法運(yùn)算前,隱式類(lèi)型轉(zhuǎn)換會(huì)嘗試將表達(dá)式中的變量轉(zhuǎn)換為 number 類(lèi)型。如:'1' + 1 會(huì)得到結(jié)果 11。
null 轉(zhuǎn)化為 number 時(shí),會(huì)轉(zhuǎn)換成 0。
undefined 轉(zhuǎn)換為 number 時(shí),會(huì)轉(zhuǎn)換為 NaN。
5、JSON.stringify
console.log( JSON.stringify({a: undefined}) ); // '{}'
console.log( JSON.stringify({b: null}) ); // '{b: null}'
console.log( JSON.stringify({a: undefined, b: null}) ); // '{b: null}'JSON 會(huì)將 undefined 對(duì)應(yīng)的 key 刪除,這是因?yàn)?JSON 自身的轉(zhuǎn)換原則。在 undefined 的情況下,有無(wú)該條數(shù)據(jù)是沒(méi)有區(qū)別的,因?yàn)樗麄冊(cè)诒憩F(xiàn)形式上并無(wú)不同。
let obj1 = { a: undefined };
let obj2 = {};
console.log(obj1.a); // undefined
console.log(obj2.a); // undefined6、let undefiend = 'test'
function test(params) {
let undefined = 'test'; // 該作用域內(nèi)undefined為一個(gè)變量,賦值為test
return params === undefined;
}
test(); // false
test(undefined); // false
test('test'); // ture
let undefined = 'test'; // Uncaught SyntaxError: Identifier 'undefined' has already been declaredJavaScript 對(duì)于 undefined 的限制方式為全局創(chuàng)建了一個(gè)只讀的 undefined,但是并沒(méi)有徹底禁止局部 undefined 變量的定義。
請(qǐng)?jiān)谌魏螘r(shí)候,都不要對(duì) undefined 變量進(jìn)行覆蓋,就算是你的 JSON 轉(zhuǎn)換將 undefined 轉(zhuǎn)換為 '' ,也不要通過(guò)該操作進(jìn)行,這將是及其危險(xiǎn)的行為。
四、建議
如果你需要使用 undefined 定義空值,請(qǐng)不要采取以下兩種方式:
- let a;
- let a = undefined;
進(jìn)而采取下面這種方式顯式聲明 undefined:
- let a = void 0;
附:null在類(lèi)型判斷時(shí)為什么是object
這是一段歷史,1995年Javascript誕生之初, 在實(shí)現(xiàn)js類(lèi)型判斷的方法時(shí)(也就是typeof),數(shù)值是以32位存儲(chǔ)的,由標(biāo)志位(1~3位)和數(shù)值組成。標(biāo)志位存儲(chǔ)的是低位的數(shù)據(jù)。這里有五種標(biāo)志位:
- 000 表示對(duì)象
- 1 表示整數(shù)
- 010 表示浮點(diǎn)數(shù)
- 100 表示字符串
- 110 表示布爾類(lèi)型
有兩個(gè)特殊值:
- undefined用-2^30表示
- null用全0表示
這不巧了嗎這不是,null的低位也是000,所以誤打誤撞成為了object,這一點(diǎn)一直被認(rèn)為是個(gè)bug,直到es6的時(shí)候typeof null === 'null'的提案被否決,typeof null === 'object'變成了feature,也就是說(shuō)這個(gè)"bug"不會(huì)被“修復(fù)”了
總結(jié)
到此這篇關(guān)于undefined和null區(qū)別的文章就介紹到這了,更多相關(guān)undefined和null的區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- javascript中undefined與null的區(qū)別
- JavaScript undefined及null區(qū)別實(shí)例解析
- JavaScript中undefined和null的區(qū)別
- javascript中undefined與null的區(qū)別
- JavaScript中Null與Undefined的區(qū)別解析
- JavaScript中的null和undefined區(qū)別介紹
- 詳解JavaScript中undefined與null的區(qū)別
- js中 關(guān)于undefined和null的區(qū)別介紹
- JS基礎(chǔ)之undefined與null的區(qū)別分析
- JS中null和undefined的區(qū)別
相關(guān)文章
JS中數(shù)組與對(duì)象相互轉(zhuǎn)換的實(shí)現(xiàn)方式
這篇文章主要介紹了JS中數(shù)組與對(duì)象相互轉(zhuǎn)換的實(shí)現(xiàn)方式,文章通過(guò)代碼示例講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-04-04
原生javascript實(shí)現(xiàn)圖片按鈕切換
這篇文章主要介紹了原生javascript實(shí)現(xiàn)圖片按鈕切換,需要的朋友可以參考下2015-01-01
JavaScript輸出當(dāng)前時(shí)間Unix時(shí)間戳的方法
這篇文章主要介紹了JavaScript輸出當(dāng)前時(shí)間Unix時(shí)間戳的方法,涉及javascript中Date及getTime等函數(shù)操作時(shí)間的使用技巧,需要的朋友可以參考下2015-04-04
Bootstrap進(jìn)度條與AJAX后端數(shù)據(jù)傳遞結(jié)合使用實(shí)例詳解
這篇文章主要介紹了Bootstrap進(jìn)度條與AJAX后端數(shù)據(jù)傳遞結(jié)合使用,需要的朋友可以參考下2017-04-04
小程序中canvas的drawImage方法參數(shù)使用詳解
這篇文章主要介紹了小程序中canvas的drawImage方法參數(shù)使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07
JavaScript截取字符串的2個(gè)函數(shù)介紹
這篇文章主要介紹了JavaScript截取字符串的2個(gè)函數(shù)介紹,它們分別是substring和substr函數(shù),本文用實(shí)例講解了它們的用法,需要的朋友可以參考下2014-08-08
javascript實(shí)現(xiàn)生成并下載txt文件方式
這篇文章主要介紹了javascript實(shí)現(xiàn)生成并下載txt文件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09
JS簡(jiǎn)單實(shí)現(xiàn)DIV相對(duì)于瀏覽器固定位置不變的方法
這篇文章主要介紹了JS簡(jiǎn)單實(shí)現(xiàn)DIV相對(duì)于瀏覽器固定位置不變的方法,涉及javascript針對(duì)頁(yè)面位置的運(yùn)算與動(dòng)態(tài)變換技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06

