還是一樣,先上程式碼:
<script> >var f = function g() { <BR>return 1; <BR>}; <BR>if (false) { <BR>f = function g(){ <BR>return 2; <BR>}; <BR>} <BR>alert(g()); // 2 <BR></script>
把這段程式碼丟到IE 6 裡面和chorme裡面是完全不同的兩種效果。
這裡輸出2 是在ie6裡面的效果,如果在chorme會出現g沒有定義。
這也算是JScript的bug吧。
在這裡很明顯,這裡的只是定義了g的函數表達式而已。包括在if的條件語句中,也只是定義了函數表達式,沒有去宣告函數。
那麼這樣直接存取肯定是會出錯的。
那麼對於何為聲明,何為函數表達式呢?
在ECMAScript中,創建函數的最常用的兩個方法是函數表達式和函數聲明,兩者期間的區別是有點暈,因為ECMA規範只明確了一點:函數聲明必須帶有標示符(Identifier)(就是大家常說的函數名稱),而函數表達式可以省略這個標示符:
函數宣告:
function 函數名稱(參數:可選){ 函數體}
函數表達式:
function 函數名稱(可選)(參數:可選){ 函數體}
所以,可以看出,如果不聲明函數名稱,它肯定是表達式,可如果宣告了函數名稱的話,如何判斷是函數宣告還是函數表達式呢? ECMAScript是透過上下文來區分的,如果function foo(){}是作為賦值表達式的一部分的話,那它就是一個函數表達式,如果function foo(){}被包含在一個函數體內,或者位於程式的最頂端的話,那它就是一個函數宣告。
還有一個函數表達式不太常見,就是被括號括住的(function foo(){}),他是表達式的原因是因為括號()是一個分組運算符,它的內部只能包含表達式。
你可能會想到,在使用eval對JSON進行執行的時候,JSON字串通常被包含在一個圓括號裡:eval('(' json ')'),這樣做的原因就是因為分組運算符,也就是這對括號,會讓解析器強迫將JSON的花括號解析成表達式而不是程式碼區塊。