2013-02-22 85 views
2

JavaScript中兩個模塊聲明有什麼區別? 一個在功能周圍有括號,另一個沒有?javascript中兩個聲明的區別是什麼?

一篇文章說,

公告的()周圍的匿名函數。這是由 語言要求的,因爲這與令牌功能開始語句 一直被認爲是函數聲明。包括()會改爲創建一個 函數表達式。

似乎都檢查什麼時候做同樣的事情。

var person = (function() { 
    // Private 
    var name = "Robert"; 
    return { 
     getName: function() { 
      return name; 
     }, 
     setName: function(newName) { 
      name = newName; 
     } 
    }; 
}()); 

var person = function() { 
    // Private 
    var name = "Robert"; 
    return { 
     getName: function() { 
      return name; 
     }, 
     setName: function(newName) { 
      name = newName; 
     } 
    }; 
}(); 
+0

[函數聲明](http://ecma-international.org/ecma-262/5.1/#sec-13)都不是函數表達式。 – RobG 2013-02-22 11:53:21

+0

沒有區別。 – 2013-02-22 11:53:24

+0

通常第二個需要首先通過'person()'實例化,但也許在運行時環境中存在一個錯誤。 – 2013-02-22 11:54:13

回答

3

功能有兩種類型的JavaScript - 聲明和表達式。

這是二者之間的差:

  1. 函數聲明懸掛。這意味着您可以在程序出現之前調用該函數,因爲在JavaScript中聲明已懸掛
  2. 函數表達式可以立即調用。函數聲明不能​​。這是因爲表達式表示(或返回一個值)。函數表達式表示一個函數。

函數聲明的一個例子:

foo("bar"); 

function foo(bar) { 
    alert("foo" + bar); 
} 

上述方案將工作,因爲foo是一個函數聲明。如foo被聲明爲undefined,懸掛再後來分配一個函數表達式的值

foo("bar"); // throws an error, foo is undefined - not a function 

var foo = function (bar) { 
    alert("foo" + bar); 
}; 

上述程序將不工作。當它被調用時它是undefined

函數式的一個例子:

(function (bar) { 
    alert("foo" + bar); 
}("bar")); 

上述功能將被立即調用,因爲它是一個函數表達式。

function (bar) { 
    alert("foo" + bar); 
}("bar"); // throws an error, can't call undefined 

上述函數不會立即被調用,因爲它是一個函數聲明。請記住,聲明不表示(或返回值)。所以這就像試圖調用undefined作爲一個函數。

函數如何成爲表達式?

如果在預期表達式的上下文中使用函數,那麼它將被視爲表達式。否則它被視爲聲明。

  1. 你賦值給一個變量(即identifier = expression):當

    表達式的預期。

  2. 括號內(即(expression))。
  3. 作爲操作符的操作數(即operator expression)。

因此,以下是所有函數表達式:

var foo = function() {}; 
(function() {}); 
~function() {}; 

其他的都是一個函數聲明。簡而言之,如果你的功能沒有任何事情發生,它就是一個聲明。

看到這個代碼:https://github.com/aaditmshah/codemirror-repl/blob/master/scripts/index.js#L94

以下功能isExpression用於測試一些任意JavaScript代碼是否是一個表達式或不:

function isExpression(code) { 
    if (/^\s*function\s/.test(code)) return false; 

    try { 
     Function("return " + code); 
     return true; 
    } catch (error) { 
     return false; 
    } 
} 

希望這將清除在你的心中有任何懷疑。

簡而言之:

  1. 函數表達式表達或返回一個值(在這種情況下的函數)。因此可以立即調用,但在程序出現之前無法調用它。
  2. 函數聲明是的懸掛。因此可以在程序出現之前調用它。但由於它不表示任何價值,因此不能立即調用。
1

不同的是,書寫時:

var foo = (function() { 
      ... 
}()); 

使用的(多餘的,但很有用)分組()是一種常見的編碼風格,使之清楚很像右邊第一行很可能是立即調用的函數表達式(IIFE)。然而,在第二:

var foo = function() { 
      ... 
}(); 

它不直到你讀的最後一行,這可能是相當多的線下變得明顯。直到到達最後一行,你可能以爲你在讀一個普通的任務:

var foo = function() { 
      ... 
}; 

注意,括號可以在一個普通的分配也可用於:

var foo = (function() { 
      ... 
}); 

,但在這種情況下,他們真的是多餘的(並且由於將它們用於IIFE的慣例可能會引起誤導)。

An Important Pair of Parens

1

在目前情況下有一個爲解釋沒有區別。寫模塊通常最好的方式是通過包裝用括號功能:

var person = (function() { 
    // Private 
    var name = "Robert"; 
    return { 
     getName : function() { 
      return name; 
     } 
    }; 
}()); 

這是因爲語法是更清潔,這顯然是要調用它宣佈後立即功能。還有一個原因是因爲:

(function() { 
    //some stuff 
}()); 

工作,但

function() { 
    //some stuff 
}(); 

這不會。

通過包裝在每次使用常見的作弄風格通常是:-)一件好事時間的函數。

相關問題