null == undefined ?

2021-02-16 前端大全

(點擊上方公眾號,可快速關注)

作者:一像素

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】函數定義了形參,但沒有傳遞實參

//函數定義了形參 a

function fn(a) {

    console.log(a); //undefined

}

fn(); //未傳遞實參

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

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

void 0 ; // undefined

void false; //undefined

void []; //undefined

void null; //undefined

void 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); // 0

Number(undefined); // NaN

 

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

null == 0 ; //false

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

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

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

4、總結

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

覺得本文對你有幫助?請分享給更多人

關注「前端大全」,提升前端技能

相關焦點

  • undefined 和 null 的區別
    函數的形參沒有傳遞實參進去,形參為 undefined4.>null 的情況一般是我們設置的,他是一個 對象類型的,使用 typeof 會輸出 Object 類型;他可以看做 零5 + null; // 510 * null;   // 0還有他和 undefined 是相等的,但不全等:
  • 深入探究:null 和 undefined 究竟有何區別?
    簡單區分總的來說 null 和 undefined 都代表空,主要區別在於 undefined 表示尚未初始化的變量的值,而 null 表示該變量有意缺少對象指向。MDN 中給出的定義null值 null 是一個字面量,不像 undefined ,它不是全局對象的一個屬性。
  • 如何在JavaScript中處理null和undefined?
    怎樣才能最大程度減少由 null、undefined,或在運行時未初始化的值所引發的錯誤,有哪些最佳策略呢? 有些語言針對這類情況有內置的解決方案。在某些靜態類型的語言中,你可以認定 null 和 undefined 是非法值,並且讓你的程式語言在編譯時拋出 TypeError。但即使在這種語言中,也不能阻止 null 輸入在運行時流入程序。
  • JS面試題:undefined 和 null 之間有什麼區別?
    在了解undefined和null之間的區別之前,我們先得了解它們之間的相似之處。它們都屬於JavaScript的7種原始類型。undefined); //logs false console.log(Boolean(null)); //logs falseconsole.log(Boolean(undefined)); //logs false現在讓我們說說差異之處。
  • 7個處理JavaScript值為undefined的技巧
    他們似乎都可以定義一個空值,而且 當你進行 在做null ===undefined 的比較時,結果是true。現在的大多數語言,像Ruby, Python or Java,他們有一個單獨的空值(nil 或 null),這視乎才是一個合理的方式。而在JavaScript裡,當你要獲取一個變量或對象(未初始化)的值時,js引擎會返回 undefined。
  • 分析Array.apply(null, { length: 20 })
    二、表達式Array.apply(null, { length: 2 })的值先溫故下基礎,為了方便驗證將表達式改成Array.apply(null, { length: 2 }),即length的值改成2基礎1: Array構造函數直接調用Array函數跟new方式調用是等價的,即:var a = Array(2); // 等價於var a = new
  • 處理 undefined 值的7個建議
    閱讀 7 tips to handle undefined in JavaScriptDmitri Pavlutin | 15 Apr 2017 一文之後的小結,有刪減。引言undefined 是 JavaScript 中的一個特殊值,另一個特殊值則是 null,這兩個特殊值還分別對應了一種數據類型:Undefined 和 Null。
  • null為什麼被typeof錯誤的判斷為了'object'
    一、typeoftypeof 操作符唯一的目的就是檢查數據類型類型typeof 結果基本類型undefined"undefined"Boolean"boolean"Number"number"String"string"BigInt (ECMAScript 2020 新增)"bigint"
  • 一文搞懂 NULL 和 nullptr 的區別
    下面我們來修改一下上面的程序,將 NULL 替換為 nullptr,修改後如下所示:#include <iostream>using namespace std; void func(int x) { cout
  • C++11(5)nullptr引入以及關於C/C++中NULL、nullptr對比
    但是實際上,用NULL代替0表示空指針在函數重載時會出現問題,舉例如下:#include <iostream>using namespace std; void func(void* i){     cout <
  • 為什麼建議你用nullptr而不是NULL?
    null.cppnull.cpp: In function 'int main()':null.cpp:5:17: error: invalid conversion from 'void*' to 'int*' [-fpermissive]  int *a =(void*)p;所以不能將NULL定義為(void*)0。
  • NDK undefined reference to 錯誤
    前幾天在Android NDK下用C++編寫程序時,出現了一個「NDK undefined reference to」的編譯錯誤。
  • C++的「坑」之一:undefined reference
    有時候編譯C++,會遇到錯誤,undefined reference 錯誤。怎麼定位這個錯誤呢?