2013-02-02 44 views
2

我測試了以下代碼:變量聲明在函數聲明之前是否有優先權?

(function(){ 
    var x = false; 
    function x(){ 
    return true; 
    } 
    return typeof x; 
})(); 

它返回 「布爾」。只有當我評論第二行時:

(function(){ 
    //var x = false; 
    function x(){ 
    return true; 
    } 
    return typeof x; 
})(); 

它返回「功能」。 這意味着如果某人之前在代碼的某處聲明瞭一個變量,那麼使用相同名稱的函數聲明將會失敗,對吧?請有人向我解釋。 謝謝!

回答

4

在JavaScript中,函數聲明被視爲先寫入。然後是變量聲明。 (如果有的話,這種特定的排序很少)

在變量聲明中,任何賦值部分都被視爲發生在函數中實際出現var語句的位置的單獨表達式語句。因此:

function foo() { 
    // ... some code ... 
    if (whatever) { 
    var x = whatever + 1; 
    } 
} 

是像對待:

function foo() { 
    var x; 
    // ... some code ... 
    if (whatever) { 
    x = whatever + 1; 
    } 
} 

因此整體就好像它是你的第一個樣品處理:

(function() { 
    function x() { 
    return true; 
    } 
    var x; 
    x = false; 
    return typeof x; 
})(); 

還要注意函數和變量都有一個共同的名字空間。對於已聲明的變量名沒有賦值部分的var聲明不起作用。 (至少,我認爲它沒有意義的效果,但JavaScript有奇怪的黑角......)

+0

不知道,謝謝! – paperstreet7

+0

我希望函數聲明能夠轉換成首先寫入的函數表達式賦值?即代碼被視爲'var x; x =函數x(){...}; x = false; ...' – Bergi

+0

@Bergi我覺得JavaScript引擎是免費的,但這兩者並不完全一樣。在function函數和形式參數的左括號之間的函數實例化中提供的名稱與函數中的代碼綁定,與函數中的代碼無關。它(類似於)Lisp中的'letrec'。 (不過,我不知道是否可以構建一個顯示差異的示例。) – Pointy