一道騰訊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.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其他的版本是否是可以的,還請知道的大神解釋下?