舉個(gè)簡單的栗子:
? ? ? ? A和B兩個(gè)人肚子都很餓,要去吃飯。A已打電話到飯店預(yù)約位置,B則打算下班后考察下再做決定。對于飯店來說,A基本上就是他的客戶了,只不過還沒見到人來,定為null(畢竟交易還沒產(chǎn)生),而對飯店來說,B是誰啊,他們根本沒聽到過這個(gè)人,為undefined
然而,概念還是念叨念叨的
從字面上理解:undefined 不明確的,不知道的,例如var a;我們聲明了一個(gè)變量但是沒有給定初始值,但是這個(gè)a代表著啥,boolean?? ?string?? ?number?? ?object?? ?function? 都有可能。而 var a = null;的話,則直接聲明了a是有的,但是它的值是空的,沒有的,如果把他們同時(shí)跟一個(gè)數(shù)值相加減,也正解釋了為啥? 3+null = 0 而? 3+undefined得到的結(jié)果是NaN了。
這倆貨是一堆好兄弟,相同而又不同。我們都知道JavaScript幾個(gè)基本上數(shù)據(jù)類型:
Boolean、Null? Undefined? String? Number? Symbol(ES6新增),這倆貨占據(jù)兩席位置,分量如此重,不得不說,不得不重視起來他們啊。
Undefined 其實(shí)代表的是不存在的值,Null是字面量同時(shí)也是語言中的關(guān)鍵詞,表示無法識別的對象值。他們都沒有屬性和方法,也不能給其屬性賦值。他們的布爾值都是false,說到布爾值為false的,通常包括? NaN 、 0、空字符串、Null 、Undefined 這五種常見的對象。他們之間的關(guān)系,可以這樣總結(jié):
Null? == 0? ?//false
Undefined == 0? //false
undefined == ""? ?//false
null == ""? ? ?//false
null == NaN? ?//false
undefined? == NaN? //false
undefined == null? ?//true
undefined === null? ? //false
null 是一個(gè)特殊的“對象”,相當(dāng)于一個(gè)空對象的預(yù)期。而undefined就是“未定義”,沒有。實(shí)際中更加推薦使用null,對他們執(zhí)行typeof分別是
typeof? ?undefined? ? //undefined
typeof? ? null? ? ? ? ? ? //object
相似之處
二者是不可變的,都沒有自己的屬性和方法,如果你試圖給他們增加方法或者屬性,都會產(chǎn)生類型錯(cuò)誤。各自都是孤家寡人,不用拖家?guī)Э诘?,一人吃飽全家不餓。都是“空”的東西
不同點(diǎn)
“類型”不同,undefined代表了一個(gè)意想不到的沒有的值,null是預(yù)期沒有值的代表,至于如何區(qū)分他們,下文有介紹
何種情況下會產(chǎn)生undefined呢?
當(dāng)聲明一個(gè)變量的時(shí)候,比如 var? a;? ?//undefined
訪問不存在的對象的時(shí)候 var? obj = {a:1};? ? var c = obj.c;? ? //undefined
當(dāng)數(shù)組中的索引不存在的時(shí)候? var arr = [1,2,3];? ?arr[5];? ? //undefined
定義一個(gè)function,當(dāng)沒有返回值的時(shí)候,返回的也是undefined
何種情況下會產(chǎn)生null呢?
當(dāng)你試圖去獲取一個(gè)不存在的DOM的時(shí)候會返回null
程序猿自己return null
說了這么多,那么問題來了,如何區(qū)分一個(gè)變量究竟是null還是undefined呢?下面為大家提供一個(gè)方法以示區(qū)分:
Object.prototype.toString.apply(null)? ?//? [object Null]
Object.prototype.toString.apply(undefined)? //? [object Undefined]
做一個(gè)延伸(別問我為啥去做這個(gè)操作,因?yàn)槲沂巧窠?jīng)病)
如果我分別用一個(gè)Number? String? 分別跟? undefined? null做加減運(yùn)算,會產(chǎn)生什么操作呢?
5 + null;? ? ?//5
5+undefined? //? NaN
"5" + null ;? ? ?//"5null"
"5"+undefined;? ? //“5undefined”
'aa'+undefined;? ?//"aaundefined"
'aa'+null;? ? ? ? ? ?//? "aanull"
"aa"*null;? ? ? ? ? //NaN
"aa"*undefined? ?//NaN
題外話:
將我們需要判斷類型的東西通過對象的原型toString轉(zhuǎn)換為字符串,簡直就是神操作,可以狠輕松的判斷很多類型,例如
Object.prototype.toString.call({})? ? ? //? [object Object]? ?
Object.prototype.toString.call([])? ? ? //? [object Array]? ?
Object.prototype.toString.call(function d(){})? ? ? //? [object Function]? ?
Object.prototype.toString.call(123)? ? ? ? ? ? //? [object Number]
Object.prototype.toString.call("123")? ? ? ?//? ?[object String]
Object.prototype.toString.call(Symbol())? ? //? [object Symbol]