Undefined與Null的一些理解

UndefinedNull

是 Javascript 中兩種特殊的原始數據類型(Primary Type),它們都只有一個值,分別對應 undefined 和 null ,這兩種不同類型的值,既有著不同的語義和場景,又表現出較為相似的行為:

undefined

undefined 的字面意思就是:未定義的值 。

這個值的語義是,希望表示一個變量最原始的狀態,而非人為操作的結果 。

這種原始狀態會在以下 4 種場景中出現:

Undefined與Null的一些理解

訪問 foo,返回了 undefined,表示這個變量自從聲明瞭以後,就從來沒有使用過,也沒有定義過任何有效的值,即處於一種原始而不可用的狀態。

【2】訪問對象上不存在的屬性

Undefined與Null的一些理解

訪問 Object 對象上的 foo 屬性,返回 undefined , 表示Object 上不存在或者沒有定義名為 foo 的屬性。數組中的元素在內部也屬於對象屬性,訪問下標就等於訪問這個屬性,返回 undefined ,就表示數組中不存在這個元素。

【3】函數定義了形參,但沒有傳遞實參

Undefined與Null的一些理解

函數 fn 定義了形參 a, 但 fn 被調用時沒有傳遞參數,因此,fn 運行時的參數 a 就是一個原始的、未被賦值的變量。

【4】使用 void 對錶達式求值

Undefined與Null的一些理解

ECMAScript 明確規定 void 操作符 對任何表達式求值都返回 undefined ,這和函數執行操作後沒有返回值的作用是一樣的,JavaScript 中的函數都有返回值,當沒有 return 操作時,就默認返回一個原始的狀態值,這個值就是 undefined,表明函數的返回值未被定義。

因此,undefined 一般都來自於某個表達式最原始的狀態值,不是人為操作的結果。當然,你也可以手動給一個變量賦值 undefined,但這樣做沒有意義,因為一個變量不賦值就是 undefined


null

null 的字面意思是:空值 。

這個值的語義是,希望表示 一個對象被人為的重置為空對象,而非一個變量最原始的狀態 。

在內存裡的表示就是,棧中的變量沒有指向堆中的內存對象,即:

Undefined與Null的一些理解

當一個對象被賦值了null 以後,原來的對象在內存中就處於遊離狀態,GC 會擇機回收該對象並釋放內存。

因此,如果需要釋放某個對象,就將變量設置為 null,即表示該對象已經被清空,目前無效狀態。

試想一下,如果此處把 null 換成 undefined 會不會感到彆扭? 顯然語義不通,其操作不能正確的表達其想要的行為。

與 null 相關的另外一個問題需要解釋一下:

Undefined與Null的一些理解

typeof null == 'object'

null 有屬於自己的類型 Null

,而不屬於Object類型,typeof 之所以會判定為 Object 類型,是因為JavaScript 數據類型在底層都是以二進制的形式表示的,二進制的前三位為 0 會被 typeof 判斷為對象類型,而 null 的二進制位恰好都是 0 ,因此,null 被誤判斷為 Object 類型。

000 - 對象,數據是對象的應用
1 - 整型,數據是31位帶符號整數
010 - 雙精度類型,數據是雙精度數字
100 - 字符串,數據是字符串
110 - 布爾類型,數據是布爾值

其實,我們可以通過另一種方法獲取 null 的真實類型:

Undefined與Null的一些理解

通過 Object 原型上的toString() 方法可以獲取到JavaScript 中對象的真實數據類型,當然 undefined 類型也可以通過這種方式來獲取:

Undefined與Null的一些理解


相似性

雖然

undefined null 的語義和場景不同,但總而言之,它們都表示的是一個無效的值。 因此,在JS中對這類值訪問屬性時,都會得到異常的結果:

Undefined與Null的一些理解

ECMAScript 規範認為,既然 nullundefined 的行為很相似,並且都表示 一個無效的值,那麼它們所表示的內容也具有相似性,即有

undefined == null; //true

ECMAScript 規範認為,既然 nullundefined 的行為很相似,並且都表示 一個無效的值,那麼它們所表示的內容也具有相似性,即有

Number(null); // 0
Number(undefined); // NaN
null == 0 ; //false
Undefined與Null的一些理解

但 === 會返回 false ,因為全等操作 === 在比較相等性的時候,不會主動轉換分項的數據類型,而兩者又不屬於同一種類型:

Undefined與Null的一些理解


總結

用一句話總結兩者的區別就是:undefined 表示一個變量自然的、最原始的狀態值,而 null 則表示一個變量被人為的設置為空對象,而不是原始狀態。

所以,在實際使用過程中,為了保證變量所代表的語義,不要對一個變量顯式的賦值

undefined,當需要釋放一個對象時,直接賦值為 null 即可。


分享到:


相關文章: