在常見的強(qiáng)類型語言中宵蛀,通常有一個表示“空”的值,比如NULL县貌。但是在JavaScript中术陶,空(或者叫“無值”)有兩種選擇:undefined和null。在javascript中除了這兩個值其他都是對象煤痕。其他的基本類型都有其他對象的保證類型梧宫。但是typeof null 返回的是object接谨,這是一個一直未修復(fù)的bug。
相似之處
都是完全不可變的塘匣,沒有屬性和方法脓豪,也不能給其屬性賦值。事實(shí)上忌卤,試圖訪問或定義一個屬性將會引發(fā)一個類型錯誤(TypeError)扫夜。正如它們的名字暗示的那樣,它們是完全無效的值驰徊。
不同之處
一個重要的區(qū)別笤闯,服務(wù)于不同的目的和理由。區(qū)分這兩個值棍厂,你可以認(rèn)為undefined代表一個意想不到的沒有值而null作為預(yù)期沒有值的代表颗味。
使用Object.prototype.toString.call()形式可以具體打印類型。
undefined
undefined實(shí)際上代表了不存在的值牺弹。
有許多的方法產(chǎn)生一個undefined值的代碼脱衙,它通常遇到當(dāng)試圖訪問一個不存在的值時。在這種情況下例驹,在JavaScript這種動態(tài)弱類型語言中捐韩,只會默認(rèn)返回一個undefined值,而不是上升為一個錯誤:
- 任何聲明變量時沒有提供一個初始值鹃锈,都會有一個為undefined的默認(rèn)值
- 當(dāng)試圖訪問一個不存在的對象屬性或數(shù)組項(xiàng)時荤胁,返回一個undefined值
- 如果省略了函數(shù)的返回語句,返回undefined
- 函數(shù)調(diào)用時未提供的值結(jié)果為undefined參數(shù)值
- void操作符也可以返回一個undefined值屎债。像Underscore的庫使用它作為一個防御式的類型檢查仅政,因?yàn)樗遣豢勺兊模梢栽谌魏紊舷挛囊蕾嚪祷豼ndefined
- undefined是一個預(yù)定義的全局變量(不像null關(guān)鍵字)初始化為undefined值
null
通常用作一個空引用一個空對象的預(yù)期盆驹,就像一個占位符圆丹。typeof的這種行為已經(jīng)被明確認(rèn)為一個錯誤,雖然提出了修正躯喇,出于后兼容的目的辫封,這一點(diǎn)已經(jīng)保持不變。這就是為什么JavaScript環(huán)境從來沒有設(shè)置一個值為null;它必須以編程方式完成廉丽。
使用null的情況:
- Dom倦微,它是獨(dú)立于語言的,不屬于ECMAScript規(guī)范的范圍正压。因?yàn)樗且粋€外部API欣福,試圖獲取一個不存在的元素返回一個null值,而不是undefined焦履。
- 如果你需要給一個變量或?qū)傩灾付ㄒ粋€不變值拓劝,將它傳遞給一個函數(shù)雏逾,或者從一個函數(shù)返回null,null幾乎是最好的選擇郑临。
- JavaScript使用undefined并且程序員應(yīng)該使用null校套。
- 通過分配null值,有效地的清除引用牧抵,并假設(shè)對象沒有引用其他代碼笛匙,指定垃圾收集,確毕洌回收內(nèi)存妹孙。
Object.prototype.toString調(diào)用過程
- 如果值是undefined,返回"[object Undefined]"
- 如果值為null获枝,則返回"[Object Null]"
- 讓O作為調(diào)用ToObject同時傳遞this值作為參數(shù)的結(jié)果值蠢正。
- 讓class是O的內(nèi)部屬性[[Class]]的值。
- 返回的結(jié)果連接三個字符串"[object ",class,和"]"的結(jié)果的字符串值省店。