阿里巴巴js面試題1

該題難度係數: ★★★

考查的技術點:  1). 變數提升 2). 函式提升  3). 預處理  4). 呼叫順序

    var c = 1;
function c(c) {
console.log(c);
var c = 3;
}
c(2);

執行結果:

看到這結果有沒有大吃一驚?

我們現在來分析下原因。

這裡我們先來了解下“預處理”,那什麼是預處理呢?js語言本身具有預處理機制,js引擎在預處理期對所有宣告的變數和函式進行處理,就是先把變數進行宣告並讀到記憶體裡。也就是收集用var宣告的變數資訊和函式宣告資訊

還有一點是預處理時,變數和函式的優先順序,先變數後函式。當變數名和函式名一致時後者會覆蓋前者,我們看下下面的小案例,

    function b() {
}
var b
console.log(typeof b)

結果為function,這就證實了,我們剛才的結論,執行順序先變數後函式,變數名一致時,函式就會覆蓋變數。

再來說一下預處理,看一下下面的小案例:

    var a = 2  
function fn() {  
console.log(a)  
var a = 3  
}  
fn()

執行下,結果為undefined。

為什麼為undefined呢?因為這裡預處理順序是這樣的,外面宣告瞭個全域性變數a,值為2,但是裡面把a宣告成了區域性變數,函式內部的預處理順序為先宣告var a;然後console.log(a);最後a=3;所以我們呼叫函式的時候,裡面是有a,所以不會調外面的全域性a,只是裡面的a暫時還沒有值,因為a=3這賦值步驟是在console.log(a)後面執行的,所以我們執行時就看到undefined了。拓展下,如果函式裡面去掉var,那麼列印出來的值就是2了,然後全域性變數a又被賦值為3。

那好,我們現在回到我們剛才的題目上來,剛才題目的解析順序可以理解為以下步驟:

先預處理var c;

然後預處理整個c函式

function c(c) {
            console.log(c)
            var c = 3
    }

此時c的typeof為function

接下來再給c賦值,值為1,即c=1,此時c是整型變數1.typeof為number了。

最後再執行c(2)呼叫函式。所以我們呼叫的時候當然就會報c不是一個函式的錯誤了,因為他現在是一個整型變數了啊,哈哈,是不是很傷腦筋啊……

最後我們再次執行以下程式碼,證實我們的結論:

    var c = 1
function c(c) {
console.log(c)
var c = 3
}
console.log(c) // 
console.log(typeof c) // 
c(2) //

結果截圖:

再嘮叨下,這題裡面給我們設了陷阱,全域性變數名、函式名、函式形參都是c,這是面試官為了迷惑我們的,考查我們的相關知識是否理解得透徹,分析是否仔細了。畢竟是名企面試題,很注重考查基礎的……