【译】Typeof null 的历史
Update 2013-11-05:為了更好的解釋為什么 'typeof null' 的結果是 'object',我查閱了實現的 C 源碼。
在 JavaScript 中,typeof null 的結果是 object,該結果錯誤地暗示了 null 是一個對象(null 并不是一個對象,而是一個基本數據類型(的值),詳情可以查閱我的博文 categorizing values)。這其實是一個 bug,但更糟的是這個 bug 是不能修復的,因為修復這個 bug 會使已經存在的程序崩潰。下面就讓我們探索一下這個 bug 的歷史。
typeof null 這個 bug 是 JavaScript 第一個版本遺留下來的。在這個版本中,所有值都存儲在 32 位的單元中,每個單元包含一個小的**類型標簽(1-3 bits)**以及當前要存儲值的真實數據。類型標簽存儲在每個單元的低位中,共有五種數據類型:
- 000: object - 當前存儲的數據指向一個對象。
- 1: int - 當前存儲的數據是一個 31 位的有符號整數。
- 010: double - 當前存儲的數據指向一個雙精度的浮點數。
- 100: string - 當前存儲的數據指向一個字符串。
- 110: boolean - 當前存儲的數據是布爾值。
如果最低位是 1,則類型標簽標志位的長度只有一位;如果最低位是 0,則類型標簽標志位的長度占三位,為存儲其他四種數據類型提供了額外兩個 bit 的長度。
有兩種特殊數據類型:
- undefined(JSVAL_VOID) 的值是 -2**30(-2 的 30 次方) (一個超出整數范圍的數字)
- null(JSVAL_NULL) 的值是機器碼 NULL 指針(null 指針的值全是 0)。或者:object 類型的類型標簽 + 0 的引用。
現在可以很明顯地知道為什么 typeof 操作符會認為 null 是對象了:typeof 操作符檢測 null 的類型標簽位時發現是 000 (存放機器碼 NULL 指針的存儲單元中的所有數據位都是 0,所以低三位也是 0)。下面是 typeof 操作符的機器碼:
JS_PUBLIC_API(JSType)JS_TypeOfValue(JSContext *cx, jsval v){JSType type = JSTYPE_VOID;JSObject *obj;JSObjectOps *ops;JSClass *clasp;CHECK_REQUEST(cx);if (JSVAL_IS_VOID(v)) { // (1) 檢查是否為 undefinedtype = JSTYPE_VOID;} else if (JSVAL_IS_OBJECT(v)) { // (2) 檢查是否為 object(低三位是 000)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;}return type;} 復制代碼上面代碼的運行步驟:
- 在步驟(1)中,機器首先檢查值 v 是否是 undefined (VOID)。該檢查是通過比較值是否相等來完成的:
- 步驟(2)檢查值是否具有 object 類型的類型標簽。如果該值具有 object 類型的類型標簽,并可以調用(3)或者其內部屬性 [[Class]] 標記它為函數(4),則該值是一個函數;否則,該值就是一個對象。這就是 typeof null 表達式生成的結果。
- 隨后檢查分別為是否為 number,string 以及 boolean。甚至沒有專門的步驟來檢查是否為 null,該檢查可通過如下的 C 宏定義來實現:
這或許看起來是一個非常明顯的 bug,但是不要忘了實現 JavaScript 第一個版本的時間非常緊迫。
鳴謝:感謝 Tom Schuster(@evilpies) 指引我去看傳統 JavaScript 的源碼。
Source Link ?
- The history of “typeof null”
本文翻譯自 Dr. Axel Rauschmayer 的博文,侵刪。
轉載請聯系作者并注明出處。
Translator Info ?
- GitHub
- Email: web.taox@gmail.com
總結
以上是生活随笔為你收集整理的【译】Typeof null 的历史的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQL Server配置delegati
- 下一篇: 2018,抢票大作战