為什麼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!傻逼,是truetypeof null === "undefined"是多少?false!傻逼,是truetypeof null === "undefined"是多少?false!傻逼,是true
typeof null === "undefined"是多少?false!傻逼,是true
...typeof null === "undefined"是多少?false!傻逼,是truetypeof null === "undefined"是多少?false!傻逼,是truetypeof 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 的疊加態。求值後,有 的概率坍縮為狀態 null, 有 的概率坍縮為狀態 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返回的值是有出入的,可至於為什麼會同時出現這種情況,而且出現不穩定的次數,難道這個題真的有什麼陰謀嗎……