ㄟ問你喔,null, undefined 和 not defined 是差在哪?
在探討這三者的差異前,必須先知道在 JavaScript 裡面有分原始型別及物件型別,其中原始型別又分為 7 種原始資料型別 ( Primitive Data Type ):
- 字串 (string type)
- 布林值 (Boolean type)
- 數字 (number type)
- 整數數值 (BigInt type)
- undefined (undefined type)
- null (null type)
- symbol (symbol type)
原始資料型別與原始值
這樣看來undefined 與 null都是屬於原始資料型別!
但請注意,這邊特別列出了type,不是因為吃飽特閒,而是因為刻意要強調原始資料「型別 (type)」這件事。
更仔細去看 MDN 文件的話,所有的原始資料型別都有「原始值 (primitive value)」,而這個原始值是不可再被更改的,例如:布林值有兩種原始值,true 及 false,而這兩種原始值不可更動(但如果是變數的值,就可以更動)。
比較 undefined 與 null
假如宣告一個變數 foo1,但不賦予值,foo1 的回傳是 undefined:
let foo1;
console.log(foo1)// undefined
但假如宣告一個變數 foo2,並賦予值為 null,foo2 的值就是 null:
let foo2 = null;
console.log(foo2); // null
也就是說,這兩者的差異在於「有沒有對變數賦予值」吧,哎唷,原來事情就是這麼簡單而已啊。
不不不…!!!!!! 不是的。
記得剛剛為什麼要特別去強調資料「型別」的type這件事嗎?
請注意,型別和值是兩回事喔,如果剛剛的 console.log 顯示的是變數的值,那麼(摸摸百寶袋),這一次,就換拿出 typeof 這個照妖鏡來看看,undefined 跟 null 這兩種值,它的型別是什麼吧。
假如用 typeof 查詢 undefined value,回傳:undefined
console.log(typeof undefined) //undefined
但同樣用 typeof 查詢 null value,回傳:object
console.log(typeof null) //object
什麼????!
唔,詭異的地方果然現形了吧!
假如 undefined 的型別是 undefined,那 null 的型別不也應該是null嗎?怎麼會是object?
相傳是 javascript 從發明之初就有的 bug,而若去更動會產生很多問題,同時,也可以在 JavaScript 規範查詢得知:
null value: primitive value that represents the intentional absence of any object value
undefined value: primitive value used when a variable has not been assigned a value
也就是,null 是有意的要去指出一個值是不存在的狀態,而undefined 則是代表一個變數還沒被指派一個值、尚未被初始化的狀態,所以每個變數在尚未被初始化前一定都有個 undefined 值。
接下來,就把目前僅有的線索製表,再用三個例子來檢視 null 與 undefined 之間的關係吧。
範例一:
console.log(null !== undefined) // true
根據圖表二,兩個不同型別的值,會被視為不相等,undefined的型別是undefined,而 null 用 typeof 查詢的結果是 object,兩者型別不同,比較結果為true。
範例二:
console.log(null == undefined) // true
哇勒,到底為什麼剛剛明明不相等,現在又相等了???
undefined 是變數在宣告的時候沒有賦予值,而 null 是賦予變數一個「空值」,根據圖表二,兩者在轉換成相同型別之後,進行比較時,值會是相等的,結果會是 true。
由於 null 與 undefined 都是 falsy 值,推測這可能會是兩者值相等的原因。
註1:falsy 值並不等於 false,但本文並不會解釋 falsy 值,可參閱:Truthy 與 Falsy。註2:這邊特別注意的是,null、undefined 並不等於 0 喔!
— —
範例三:
console.log(null === undefine) // false
根據圖表二,因為null用 typeof 查詢結果是object、undefined的型別是undefined,兩者型別不相等,所以比較結果為 false。
undefined 等於 not defined 嗎?
嘖嘖嘖,最後的最後,還要來比較一下 undefined 與 not defined,這兩者也是常常會很令人困惑的。
但我先說,答案很肯定是:NO。
既然現在已經知道,undefined 為 JS 七種資料型別之一,當宣告一個變數,但未賦予值,它預設的值就會是 undefined,大概於類似電腦告訴你:
「ㄟ,我知道是有這個人啦,但齁,我不知道是從哪裡來的啦,歹勢!」
那什麼時候會出現 not defined 呢?
當看到回傳 xxx is not defined 的時候,是代表某一個變數根本都還不存在,也就是說變數連被宣告的這個動作都還沒有,類似於電腦告訴你:
「ㄟ,沒這個人啦,搞不好齁,他連投胎都還沒去!」
以上,為我自己對 null, undefined 與 not defined 的理解,如有錯誤的部分請不吝指正,謝謝。
參考資料
1. 嚴格不等於
2. 相等比較
3. 你懂 JavaScript 嗎?#4 型別(Types)
4. An Essential Guide to JavaScript null
5. https://tc39.es/ecma262/#sec-null-value