javascript 中的 null
:既是對象,又不是對象,史稱「薛定諤的對象」。
typeof null === 'object'; null instanceof Object === false
而
null instanceof null
會拋出異常:
Uncaught TypeError: Right-hand side of 'instanceof' is not an object
這是一個歷史遺留下來的 feature(or bug?),The history of “typeof null”
在 javascript 的最初版本中,使用的 32 位系統,為了性能考慮使用低位存儲了變量的類型信息:
- 000:對象
- 1:整數
- 010:浮點數
- 100:字符串
- 110:布爾
有 2 個值比較特殊:
- undefined:用 - (−2^30)表示。
- null:對應機器碼的 NULL 指針,一般是全零。
在第一版的 javascript 實現中,判斷類型的代碼是這么寫的:
if (JSVAL_IS_VOID(v)) { // (1) type = JSTYPE_VOID; } else if (JSVAL_IS_OBJECT(v)) { // (2) obj = JSVAL_TO_OBJECT(v); if (obj && (ops = obj->map->ops, ops == &js_ObjectOps ? (clasp = OBJ_GET_CLASS(cx, obj), clasp->call || clasp == &js_FunctionClass) // (3,4) : ops->call != 0)) { // (3) type = JSTYPE_FUNCTION; } else { type = JSTYPE_OBJECT; } } else if (JSVAL_IS_NUMBER(v)) { type = JSTYPE_NUMBER; } else if (JSVAL_IS_STRING(v)) { type = JSTYPE_STRING; } else if (JSVAL_IS_BOOLEAN(v)) { type = JSTYPE_BOOLEAN; }
(1):判斷是否為 undefined
(2):如果不是 undefined,判斷是否為對象
(3):如果不是對象,判斷是否為數字
(4):。。。
這樣一來,null
就出了一個 bug。根據 type tags 信息,低位是 000
,因此 null
被判斷成了一個對象。這就是為什么 typeof null
的返回值是 object
。
關於 null
的類型在 MDN 文檔中也有簡單的描述:typeof - javascript | MDN
在 ES6 中曾有關於修復此 bug 的提議,提議中稱應該讓 typeof null === 'null'
http://wiki.ecmascript.org/do...:typeof_null 但是該提議被無情的否決了,自此 typeof null
終於不再是一個 bug,而是一個 feature,並且永遠不會被修復。
這是 JavaScript 最初實現的一個 bug,目前的 JavaScript 引擎已經不這么去實現了,但是這個 bug 卻一直流傳了下來。
至於對象的內部表示,不同的 JavaScript 引擎實現起來都是不一樣的,單說說 V8 吧。
v8引擎是如何知道js數據類型的? (原文太長我就不貼過來了)