js面試題

一道騰訊js面試題

題目如下:

f = function() {return true;}; 
g = function() {return false;}; 
(function() { 
   if (g() && [] == ![]) { 
      f = function f() {return false;}; 
      function g() {return true;} 
   } 
})(); 
alert(f()); // true or false ? 

對作用域鏈(scope chain)、執(zhí)行環(huán)境(execution context)、變量對象(variable object)的理解
命名函數(shù)表達式,參見這里
以上知識點在不同瀏覽器(主要為:IE和Firefox)的實現(xiàn)差異
相等操作符的隱式類型轉(zhuǎn)換規(guī)則
首先,代碼簡化為(1):

f = function() {return true;}; 
g = function() {return false;}; 
(function() { 
   alert(g()); 
   function g() {return true;} 
})(); 

上面的例子中,當控制器進入匿名函數(shù)的執(zhí)行環(huán)境后,初始化活動對象,函數(shù)聲明g被放到了執(zhí)行環(huán)境的變量對象集合中,property為g,值為g函數(shù)對象,當執(zhí)行g(),返回true。
這個應該可以理解,內(nèi)部閉合作用域下g()實際調(diào)用的是內(nèi)部定義的方法。

將上面的代碼稍加改變(2):

f = function() {return true;}; 
g = function() {return false;}; 
(function() { 
   alert(g()); 
   if (true) { 
      function g() {return true;} 
   } 
})(); 

上面代碼,結果應該與(1)相同,但Firefox處理結果出現(xiàn)了不同返回false,暫且把這看作是Firefox的bug(雖然Firefox不認為這是個Bug)。

分析:在Firefox中,出現(xiàn)在條件語句中的代碼塊不做活動對象初始化的處理(Firefox把它當作塊作用域??),即把上例的if (true) 修改為 if (false) 結果是一樣的。

ps:58.xx 版本的谷歌下直接顯示g() 未定義直接js報錯了 (Uncaught TypeError: g is not a function)

到此為止,已經(jīng)可以確定g()執(zhí)行后的值是true還是false了。

整合一下(3):

f = function() {return true;}; 
g = function() {return false;}; 
(function() { 
   if (g()) { 
      alert("能看到這個警告框,說明你的瀏覽器不是Firefox"); 
      function g() {return true;} 
   } 
})(); 

繼續(xù)分解代碼(4):

f = function() {return true;}; 
g = function() {return false;}; 
(function() { 
   f = function() {return false;}; 
})(); 
alert(f()); 

代碼運行,無一例外的返回false,這正是我們想要的結果。
然后稍作改變(5):

f = function() {return true;}; 
g = function() {return false;}; 
(function() { 
   f = function f() {return false;}; 
})(); 
alert(f()); 

經(jīng)過稍加修改后,這次掉鏈子的輪到IE了,IE竟然返回了true!!!這是IE的Bug,參見:

http://www.cn-cuckoo.com/main/wp-content/uploads/2009/12/named-function-expressions-demystified.html#named-expr

http://www.w3help.org/zh-cn/causes/SJ9001

至于[]==![]的結果,參考《Javascript類型轉(zhuǎn)換規(guī)則》
typeof([])是個object typeof(![])就成了Boolean
alert([])是個空 alert(![]) 是個false javascript中一切空或者0在做比較的時候都會轉(zhuǎn)化成boolean值false所以 答案很明顯了 false equals false
樓上的答案不標準,也可以說有些錯誤。
執(zhí)行類型轉(zhuǎn)換的規(guī)則如下:
如果一個運算數(shù)是 Boolean 值,在檢查相等性之前,把它轉(zhuǎn)換成數(shù)字值。false 轉(zhuǎn)換成 0,true 為 1。
如果一個運算數(shù)是字符串,另一個是數(shù)字,在檢查相等性之前,要嘗試把字符串轉(zhuǎn)換成數(shù)字。
如果一個運算數(shù)是對象,另一個是字符串,在檢查相等性之前,要嘗試把對象轉(zhuǎn)換成字符串。
如果一個運算數(shù)是對象,另一個是數(shù)字,在檢查相等性之前,要嘗試把對象轉(zhuǎn)換成數(shù)字。
在比較時,該運算符還遵守下列規(guī)則:
值 null 和 undefined 相等。
在檢查相等性時,不能把 null 和 undefined 轉(zhuǎn)換成其他值。
如果某個運算數(shù)是 NaN,等號將返回 false,非等號將返回 true。
如果兩個運算數(shù)都是對象,那么比較的是它們的引用值。如果兩個運算數(shù)指向同一對象,那么等號返回 true,否則兩個運算數(shù)不等。

最后大整合。

我們不僅知道結果,而且知道為啥是這結果了(6):

f = function() {return true;}; 
g = function() {return false;}; 
(function() { 
   if (g() && [] == ![]) { 
      f = function f() {return false;}; 
      function g() {return true;} 
   } 
})(); 
alert(f()); 

沒有問題的瀏覽器會返回:false

Firefox不會執(zhí)行到if條件內(nèi)部,返回:true

IE會執(zhí)行到if條件內(nèi)部(但把if內(nèi)部的f作為局部變量處理了),最后返回:true

ps:58.xx 版本的谷歌下直接顯示g() 未定義直接js報錯了 (Uncaught TypeError: g is not a function)

不清楚是不是很老的問題了,google chrome其他的版本是否是可以的,還請知道的大神解釋下?

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容

  • 一、html基礎1、你做的頁面在哪些流覽器測試過?這些瀏覽器的內(nèi)核分別是什么?IE: trident內(nèi)核Firef...
    Smallbore閱讀 971評論 0 15
  • 1.介紹js的基本數(shù)據(jù)類型。Undefined、Null、Boolean、Number、String2.介紹js有...
    lucky婧閱讀 722評論 0 5
  • 說明:一共有13題(原本14題,最后一道什么鬼,嫌棄不要了),覆蓋面比較廣,都屬于比較燒腦的類型,各種神坑;不過對...
    小pxu閱讀 2,571評論 1 14
  • 編程師小劉閱讀 210評論 0 0
  • 溫柔只會針對自己愛的人、如果他會泛濫與膚淺的針對所有人、也可為了自己內(nèi)心的堅定與執(zhí)著還有責任、請一定要等,不要失望...
    陳琳琳閱讀 79評論 0 1