1. 程式人生 > >javascript 函式宣告與函式表示式的區別

javascript 函式宣告與函式表示式的區別

還是一樣,先上程式碼:

<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的花括號解析成表示式而不是程式碼塊。