日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【译】Typeof null 的历史

發(fā)布時間:2024/9/21 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【译】Typeof null 的历史 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Update 2013-11-05:為了更好的解釋為什么 'typeof null' 的結(jié)果是 'object',我查閱了實現(xiàn)的 C 源碼。

在 JavaScript 中,typeof null 的結(jié)果是 object,該結(jié)果錯誤地暗示了 null 是一個對象(null 并不是一個對象,而是一個基本數(shù)據(jù)類型(的值),詳情可以查閱我的博文 categorizing values)。這其實是一個 bug,但更糟的是這個 bug 是不能修復(fù)的,因為修復(fù)這個 bug 會使已經(jīng)存在的程序崩潰。下面就讓我們探索一下這個 bug 的歷史。

typeof null 這個 bug 是 JavaScript 第一個版本遺留下來的。在這個版本中,所有值都存儲在 32 位的單元中,每個單元包含一個小的**類型標(biāo)簽(1-3 bits)**以及當(dāng)前要存儲值的真實數(shù)據(jù)。類型標(biāo)簽存儲在每個單元的低位中,共有五種數(shù)據(jù)類型:

  • 000: object - 當(dāng)前存儲的數(shù)據(jù)指向一個對象。
  • 1: int - 當(dāng)前存儲的數(shù)據(jù)是一個 31 位的有符號整數(shù)。
  • 010: double - 當(dāng)前存儲的數(shù)據(jù)指向一個雙精度的浮點數(shù)。
  • 100: string - 當(dāng)前存儲的數(shù)據(jù)指向一個字符串。
  • 110: boolean - 當(dāng)前存儲的數(shù)據(jù)是布爾值。

如果最低位是 1,則類型標(biāo)簽標(biāo)志位的長度只有一位;如果最低位是 0,則類型標(biāo)簽標(biāo)志位的長度占三位,為存儲其他四種數(shù)據(jù)類型提供了額外兩個 bit 的長度。

有兩種特殊數(shù)據(jù)類型:

  • undefined(JSVAL_VOID) 的值是 -2**30(-2 的 30 次方) (一個超出整數(shù)范圍的數(shù)字)
  • null(JSVAL_NULL) 的值是機器碼 NULL 指針(null 指針的值全是 0)。或者:object 類型的類型標(biāo)簽 + 0 的引用。

現(xiàn)在可以很明顯地知道為什么 typeof 操作符會認為 null 是對象了:typeof 操作符檢測 null 的類型標(biāo)簽位時發(fā)現(xiàn)是 000 (存放機器碼 NULL 指針的存儲單元中的所有數(shù)據(jù)位都是 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) 檢查是否為函數(shù)type = JSTYPE_FUNCTION;} else {type = JSTYPE_OBJECT;}} else if (JSVAL_IS_NUMBER(v)) { // 檢查是否為數(shù)字type = JSTYPE_NUMBER;} else if (JSVAL_IS_STRING(v)) { // 檢查是否為字符串type = JSTYPE_STRING;} else if (JSVAL_IS_BOOLEAN(v)) { // 檢查是否為布爾值type = JSTYPE_BOOLEAN;}return type;} 復(fù)制代碼

上面代碼的運行步驟:

  • 在步驟(1)中,機器首先檢查值 v 是否是 undefined (VOID)。該檢查是通過比較值是否相等來完成的:
#define JSVAL_IS_VOID(v) ((v) == JSVAL_VOID) // 譯注:這是一個宏定義 復(fù)制代碼
  • 步驟(2)檢查值是否具有 object 類型的類型標(biāo)簽。如果該值具有 object 類型的類型標(biāo)簽,并可以調(diào)用(3)或者其內(nèi)部屬性 [[Class]] 標(biāo)記它為函數(shù)(4),則該值是一個函數(shù);否則,該值就是一個對象。這就是 typeof null 表達式生成的結(jié)果。
  • 隨后檢查分別為是否為 number,string 以及 boolean。甚至沒有專門的步驟來檢查是否為 null,該檢查可通過如下的 C 宏定義來實現(xiàn):
#define JSVAL_IS_NULL(v) ((v) == JSVAL_NULL) 復(fù)制代碼

這或許看起來是一個非常明顯的 bug,但是不要忘了實現(xiàn) JavaScript 第一個版本的時間非常緊迫。

鳴謝:感謝 Tom Schuster(@evilpies) 指引我去看傳統(tǒng) JavaScript 的源碼。

Source Link ?

  • The history of “typeof null”

本文翻譯自 Dr. Axel Rauschmayer 的博文,侵刪。

轉(zhuǎn)載請聯(lián)系作者并注明出處。

Translator Info ?

  • GitHub
  • Email: web.taox@gmail.com

總結(jié)

以上是生活随笔為你收集整理的【译】Typeof null 的历史的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。