null == undefined ?__JavaScript

來源:互聯網
上載者:User

轉載自:

作者:一像素

www.cnblogs.com/onepixel/p/7337248.html


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


       Undefined 和 Null 是 Javascript 中兩種特殊的未經處理資料類型(Primary Type),它們都只有一個值,分別對應 undefined 和 null ,這兩種不同類型的值,即有著不同的語義和情境,但又表現出較為相似的行為:


1、undefined

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


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

var foo;console.log(foo); //undefined
       訪問foo,返回了undefined,表示這個變數自從聲明了以後,就從來沒有使用過,也沒有定義過任何有效值,即處於一種原始而停用狀態。


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

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

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


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

//函數定義了形參 afunction fn(a) {    console.log(a); //undefined}fn(); //未傳遞實參
        函數 fn 定義了形參a, 但 fn 被調用時沒有傳遞參數,因此,fn 運行時的參數 a 就是一個原始的、未被賦值的變數。

     

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

void 0 ; // undefinedvoid false; //undefinedvoid []; //undefinedvoid null; //undefinedvoid function fn(){} ; //undefined
      ECMAScript 規範 void 操作符 對任何錶達式求值都返回 undefined ,這個和函數執行操作後沒有傳回值的作用是一樣的,JavaScript中的函數都有傳回值,當沒有 return 操作時,就預設返回一個原始的狀態值,這個值就是undefined,表明函數的傳回值未被定義。


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


2、null

      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]


3、相似性

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


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

undefined == null; //true

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

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

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

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


4、總結

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




聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.