2014-02-20 41 views
1

前提條件:函數文字僅在執行相應分配時綁定到它們的名稱(除非使用匿名方式)。例如,一個可以做有條件的定義是這樣的:代碼塊中定義的內部函數的語義是什麼?

var fn; 
if (some condition) { 
    fn = function() { 
     // some code 
    }; 
} else { 
    fn = function() { 
     // some different code 
    }; 
} 

內部函數,在另一方面,表現得好像他們總是結合自己的名字,各自的範圍內,不考慮任何代碼路徑注意事項:

function outer() { 
    inner(); 
    return; 

    function inner() { 
     // some code 
    } 
} 

我的問題是,如何做到內部函數的行爲時,他們不是函數定義以外的代碼塊中定義的?以下內容應該合法嗎?標準沒有定義嗎?

function outer() { 
    if (true) { 
     inner(); 

     function inner() { 
      // some code 
     } 
    } 
} 

我與this JSFiddle測試似乎表明,它適用於大多數的瀏覽器,包括Chrome,Safari和IE 8-11,但不能在Firefox瀏覽器。這是Firefox中的錯誤嗎?

+1

這是[函數聲明vs函數表達式](http://stackoverflow.com/questions/336859/var-functionname-function-vs-function-functionname)的一個例子。函數聲明在技術上在塊內是無效的,瀏覽器的行爲會有所不同。嚴格模式禁止使用。 – elclanrs

+0

如果在IE中使用if(false),你可能會感到驚訝。我不知道他們是否或何時修復它。 –

回答

4

他們不 - 事實上一些瀏覽器將會失敗,特別是在嚴格模式下。

當執行功能,它分兩步這麼做了:

首先,所有varfunction X聲明發現懸掛在上面。請注意,在var x = 1的情況下,只有var x部分被吊起,而原來的地方仍然會有x = 1

然後代碼運行。

所有var聲明被吊起,即使它們在if塊中。例如:

function test() { 
    if(false) { 
     var x = 1; 
    } 
    alert(x); // you may expect ReferenceError, but in fact you get undefined 
}; 

這是安全的,因爲它只是說:「這個變量可能在某一時刻存在。」

然而,功能卻有很大的不同,因爲功能內容也被提起。這可能會導致在條件中定義的函數存在主要問題,因此,儘管某些瀏覽器會高興地提升它們(將最後一個定義爲最終定義),但其他瀏覽器會失敗。

function test() { 
    if(true) { 
     function derp() {alert("True");} 
    } 
    else { 
     function derp() {alert("False");} 
    } 
    derp(); // an ignorant programmer may expect True, 
      // only to find they get False, or an error 
} 

我希望這是有道理的!

+0

也http://kangax.github.io/nfe/ - 爲你的最後一點:例子#4:函數聲明是按順序解析的,不受條件塊的影響 –

+0

實際上,我鏈接的例子是關於命名函數表達式的,它讓它變得更加怪異 –

+0

清除它,謝謝 – Tobia

相關問題