關於 JavaScript 的 null 和 undefined,判斷 null 的真實類型


null、undefined

博客地址: https://ainyi.com/39

 

undefined:表示一個變量最原始的狀態,而非人為操作的結果

null:表示一個對象被人為的重置為空對象,而非一個變量最原始的狀態

 

《JavaScript高級程序設計》一書 53 頁:

由於相等和不相等操作符存在類型轉換問題,而為了保持代碼中數據類型的完整性,我們推薦使用全等和不全等操作符

記住:

null == undefined 會返回 true;

null === undefined 會返回 false;

 

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

1. undefined

undefined 的字面意思就是未定義的值,這個值的語義是,希望表示一個變量最原始的狀態,而非人為操作的結果。這種原始狀態會在以下 4 種場景中出現:

 

【1】聲明了一個變量,但沒有賦值

1 var foo;
2 console.log(foo); //undefined

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

 

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

1 console.log(Object.foo); // undefined

訪問Object對象上的 foo 屬性,同樣也返回 undefined , 表示Object 上不存在或者沒有定義名為 “foo” 的屬性

 

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

1 //函數定義了形參 a
2 function fn(a) {
3     console.log(a); //undefined
4 }
5 fn(); //未傳遞實參

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

 

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

1 void 0 ; // undefined
2 void false; //undefined
3 void []; //undefined
4 void null; //undefined
5 void function fn(){} ; //undefined

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

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

 

2. null

null 的字面意思是 空值 ,這個值的語義是,希望表示 一個對象被人為的重置為空對象,而非一個變量最原始的狀態 。 在內存里的表示就是,棧中的變量沒有指向堆中的內存對象,即:

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

 

3. 判斷 null、undefined 數據類型

獲取 null 的真實類型:

1 Object.prototype.toString.call(null); // [object Null]

通過 Object 原型上的 toString() 方法可以獲取到JavaScript 中對象的真實數據類型

 

當然 undefined 類型也可以通過這種方式來獲取:

1 // 要知道,使用 typeof 就可以鑒別 undefined 類型了
2 // typeof undefined === 'undefined'
3 Object.prototype.toString.call(undefined); // [object Undefined]

 

除此以外,還有比如 Array 的情況,因為 typeof Array 也會返回 object,檢測是否是 Array 的方法:

1 // 以下三種方法,如果是數組,返回 true
2 arr instanceof Array;
3 Array.isArray(arr); // ES5方法
4 Object.prototype.toString.call(arr); // [object Array]

 

4. 相似性

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

1 Cannot read property 'foo' of null
2 Cannot read property 'foo' of undefined

 

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

1 null == undefined; // true

不要試圖通過轉換數據類型來解釋這個結論,因為轉換類型后:

1 Number(null); // 0
2 Number(undefined); // NaN,注意 NaN 不等於任何
3 
4 // 在比較相等性之前,null 沒有被轉換為其他類型
5 null == 0 ; // false

 

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

1 null === undefined; // false,類型不相同
2 null !== undefined;  // true, 類型不相同

 

總結

用一句話總結兩者的區別就是:undefined 表示一個變量自然的、最原始的狀態值,而 null 則表示一個變量被人為的設置為空對象,而不是原始狀態。所以,在實際使用過程中,為了保證變量所代表的語義,不要對一個變量顯式的賦值 undefined,當需要釋放一個對象時,直接賦值為 null 即可

 

相關鏈接

博客地址: https://ainyi.com/39


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM