1. 程式人生 > >null == undefined ?

null == undefined ?

scrip 不能 als 數據類型 .com 回收 有意義 只有一個 logs

最近在看《JavaScript高級程序設計》一書,書中講到相等操作符(==)時說,要比較相等性之前,不能將 null 和 undefined 轉換成其他任何值,但要記住 null == undefined 會返回 true 。的確,在ECMAScipt規範中也是這樣定義的,但我認為這樣來理解這件事情,似乎有些浮於表面,網上也有很多關於這個問題的文章,下面我希望從一個全新的角度來分析 null 和 undefined ,從而理解兩者為何會相等:

1、語義和場景不同

Undefined 和 Null 是 Javascript 中兩種特殊的原始數據類型(Primary Type),它們都只有一個值,分別對應 undefined 和 null 。

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

  • 聲明了一個變量,但沒有賦值,如 var foo;
  • 訪問對象上不存在的屬性,如果 Object.foo;
var foo;
console.log(foo); //undefined

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

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

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

因此,undefined 值產生的來源一般不是人為賦值的,而是變量的原始狀態,當然,你也可以手動給一個變量賦值 undefined,但這樣做沒有意義,因為一個變量不賦值就是 undefined 。

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

技術分享

當一個對象被賦值了null 以後,原來的對象在內存中就處於遊離狀態,GC 會擇機回收該對象並釋放內存。因此,如果需要釋放某個對象,就將變量設置為null,即表示該對象已經被清空,目前無效狀態。試想一下,如果此處把 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的真實類型:

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

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

Object.prototype.toString.call(undefined) ; // [object Undefined]

2、表示的內容相似

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

技術分享

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

undefined == null; //true

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

Number(null); // 0
Number(undefined); // NaN

//在比較相等性之前,null 沒有被轉換為其他類型
null == 0 ; //false

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

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

3、總結和應用

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

原創發布 @一像素 2017.08

null == undefined ?