為什麼typeof null === "undefined"的返回值不確定?


更新: @紫雲飛 大大(微博 http://weibo.com/u/1708684567)剛寫了一篇關於這個bug來龍去脈的文章:http://www.cnblogs.com/ziyunfei/p/5618152.html ,建議大家直接看這篇文章.

另外推薦

============

這是v8的bug, reddit上有討論的了.

帖子地址在這: Javascript developers, be warned about this crazy JIT bug in V8! : javascript

帖子里說bug tracker在這裡:

https://bugs.chromium.org/p/chromium/issues/detail?id=604033

已經在這個commit

Fix "typeof null" canonicalization in crankshaft · v8/v8@7dfb5be · GitHub 里修復了


JIT直接優化成了return true了,優化前代碼為

優化後


好神……

當把循環次數調多的時候,會發現false的次數雖然不穩定但大概就在134左右,偶爾飄到200多,然後剩下的就全是true了。

而且並不是交替出現的。

就給人感覺是JS引擎還沒初始化完成似的。

也許這是Chrome51的一個BUG(我是在51里測試的),同樣的代碼在53里就沒啥問題。

那麼我琢磨呀,一個純直覺的理解就是這樣:

調用頻次高了以後觸發了更高級的JIT,然後這裡更高級的JIT有BUG導致結果是錯的,所以先是false,後就true了。

flowmemo 的回答 證實了我的猜測。


有意思的結果。

基於V8的Chrome、Opera和Vivaldi都是先出現一串false,然後穩定在true上。繼續列印出來的都是true。

node.js 4.4.5一直都是false。

edge一直都是false。

IE 11一直都是false。

火狐機器上沒有。

看起來是某個新版V8有問題。或者V8和瀏覽器集成的時候有問題。


for循環達到一定數量後,內部的代碼被jit了,然後jit有bug,以上是猜想,因為luajit也有類似的bug。


這是我大FF的優越性就體現出來了

-------------------------------

第一次執行會出現跟題主一樣的情況


271次調用foo後,變成了true,一臉懵逼

或許真相是這樣的:

typeof null === "undefined"是多少?false!傻逼,是true

typeof null === "undefined"是多少?false!傻逼,是true

typeof null === "undefined"是多少?false!傻逼,是true

typeof null === "undefined"是多少?false!傻逼,是true

.

.

.

typeof null === "undefined"是多少?false!傻逼,是true

typeof null === "undefined"是多少?false!傻逼,是true

typeof null === "undefined"是多少?true!


單獨執行typeof null === "undefined" 總是false

比如這樣:

console.log( typeof null === "undefined");
console.log( typeof null === "undefined");
……
console.log( typeof null === "undefined");

在for循環里跟題目還有小區別


Introducing JavaScript, the first Quantum Programming Language (QPL).


實際測試:

有很少的false返回,但確實是有的

環境:Chrome 51

就等大神回答了


So,還是要遵循標準,試過typeof null === "object"么?


這其實是 Google 的量子計算實驗:

null 是一個量子,它有兩種狀態:一種是 null, 一種是 undefined.

對表達式求值之前,它處於 null 和 undefined 的疊加態。

求值後,有 p 的概率坍縮為狀態 null, 有 (1-p) 的概率坍縮為狀態 undefined.

(胡扯中)


不知道大家打開瀏覽器內置調試器有沒有看到知乎的招聘廣告?!!

我覺得這個是套路,輪子哥故意拋個問題引廣大程序員「碰巧」打開內置調試器「意外發現」知乎的招聘廣告!!!輪子哥一定收了知乎很多好處!!!

我是來逗逼的,請忽略 xD

喂別亂點贊啊,知友說這個有好幾年了。


看有小夥伴貼了 reddit 地址,驗證了猜想。

不過我好奇的是,這個 test case 是怎麼被發現的。。。難道是讀源碼發現 bug 然後構建 test case =.=

=============== 割割 ===============

蟹妖。

然後並不知道何解。不過測試中發現:

- 如果直接 for 中 console 出 typeof ...,或者 for 裡面創建匿名函數來執行,而不是調用已存在的函數,似乎不會有這個問題

- 函數的情況一旦輸出 true 了之後就一直輸出 true,函數是 const 的,並且 toString 內容正確

- 我的 chrome version 51.0.2704.84 (64-bit),有問題

- node v6.2.2 沒有發現這個問題

感覺像是 V8 某些版本的 bug 吧,比如性能優化部分編譯出來的內容有問題? =.=


很好奇的試了一下,並沒有這種問題啊。

題主是偶然才碰到題目中的那種情況么?


這個應該就是兼容和版本的問題吧,不同版本的typeof null返回的值是有出入的,可至於為什麼會同時出現這種情況,而且出現不穩定的次數,難道這個題真的有什麼陰謀嗎……


分頁阅读: 1 2