在常見(jiàn)的強(qiáng)類(lèi)型語(yǔ)言中,通常有一個(gè)表示“空”的值,比如NULL。但是在JavaScript中,空(或者叫“無(wú)值”)有兩種選擇:undefined和null。在javascript中除了這兩個(gè)值其他都是對(duì)象。其他的基本類(lèi)型都有其他對(duì)象的保證類(lèi)型。但是typeof null 返回的是object,這是一個(gè)一直未修復(fù)的bug。
相似之處
都是完全不可變的,沒(méi)有屬性和方法,也不能給其屬性賦值。事實(shí)上,試圖訪問(wèn)或定義一個(gè)屬性將會(huì)引發(fā)一個(gè)類(lèi)型錯(cuò)誤(TypeError)。正如它們的名字暗示的那樣,它們是完全無(wú)效的值。
不同之處
一個(gè)重要的區(qū)別,服務(wù)于不同的目的和理由。區(qū)分這兩個(gè)值,你可以認(rèn)為undefined代表一個(gè)意想不到的沒(méi)有值而null作為預(yù)期沒(méi)有值的代表。
使用Object.prototype.toString.call()形式可以具體打印類(lèi)型。
undefined
undefined實(shí)際上代表了不存在的值。
有許多的方法產(chǎn)生一個(gè)undefined值的代碼,它通常遇到當(dāng)試圖訪問(wèn)一個(gè)不存在的值時(shí)。在這種情況下,在JavaScript這種動(dòng)態(tài)弱類(lèi)型語(yǔ)言中,只會(huì)默認(rèn)返回一個(gè)undefined值,而不是上升為一個(gè)錯(cuò)誤:
- 任何聲明變量時(shí)沒(méi)有提供一個(gè)初始值,都會(huì)有一個(gè)為undefined的默認(rèn)值
- 當(dāng)試圖訪問(wèn)一個(gè)不存在的對(duì)象屬性或數(shù)組項(xiàng)時(shí),返回一個(gè)undefined值
- 如果省略了函數(shù)的返回語(yǔ)句,返回undefined
- 函數(shù)調(diào)用時(shí)未提供的值結(jié)果為undefined參數(shù)值
- void操作符也可以返回一個(gè)undefined值。像Underscore的庫(kù)使用它作為一個(gè)防御式的類(lèi)型檢查,因?yàn)樗遣豢勺兊模梢栽谌魏紊舷挛囊蕾?lài)返回undefined
- undefined是一個(gè)預(yù)定義的全局變量(不像null關(guān)鍵字)初始化為undefined值
null
通常用作一個(gè)空引用一個(gè)空對(duì)象的預(yù)期,就像一個(gè)占位符。typeof的這種行為已經(jīng)被明確認(rèn)為一個(gè)錯(cuò)誤,雖然提出了修正,出于后兼容的目的,這一點(diǎn)已經(jīng)保持不變。這就是為什么JavaScript環(huán)境從來(lái)沒(méi)有設(shè)置一個(gè)值為null;它必須以編程方式完成。
使用null的情況:
- Dom,它是獨(dú)立于語(yǔ)言的,不屬于ECMAScript規(guī)范的范圍。因?yàn)樗且粋€(gè)外部API,試圖獲取一個(gè)不存在的元素返回一個(gè)null值,而不是undefined。
- 如果你需要給一個(gè)變量或?qū)傩灾付ㄒ粋€(gè)不變值,將它傳遞給一個(gè)函數(shù),或者從一個(gè)函數(shù)返回null,null幾乎是最好的選擇。
- JavaScript使用undefined并且程序員應(yīng)該使用null。
- 通過(guò)分配null值,有效地的清除引用,并假設(shè)對(duì)象沒(méi)有引用其他代碼,指定垃圾收集,確?;厥諆?nèi)存。
Object.prototype.toString調(diào)用過(guò)程
- 如果值是undefined,返回"[object Undefined]"
- 如果值為null,則返回"[Object Null]"
- 讓O作為調(diào)用ToObject同時(shí)傳遞this值作為參數(shù)的結(jié)果值。
- 讓class是O的內(nèi)部屬性[[Class]]的值。
- 返回的結(jié)果連接三個(gè)字符串"[object ",class,和"]"的結(jié)果的字符串值。