javascript 函式宣告與函式表示式的區別
阿新 • • 發佈:2019-01-10
還是一樣,先上程式碼:
<script>
var f = function g() {
return 1;
};
if (false) {
f = function g(){
return 2;
};
}
alert(g()); // 2
</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的花括號解析成表示式而不是程式碼塊。