2012-09-13 58 views
3

我見過2個版本的自我執行JavaScript函數:JavaScript的自動執行功能 - 不同的語法

(function() { ... })() 

(function() { ... }()) 

注意不同位置的功能執行的 「()」

這兩者有區別嗎?

+3

不,沒有區別。 – Pointy

+1

這裏關閉這個詞會引起混淆 – hsalama

+0

請參閱我的最後一段:http://stackoverflow.com/questions/12259694/whats-the-technique-that-the-google-analytics-tracking-code-uses/12259808#12259808 – fcalderan

回答

1

圓括號確保您有一個表達式(不能由function關鍵字開始),以便它可以被執行。

ECMAscript Language Specification

而且, ExpressionStatement不能用function關鍵字,因爲 可能使其曖昧與FunctionDeclaration開始。

這工作太:

(((((function() {...}))())));​ 
+0

沒有那麼多「無用」;它們確實起到了一定的作用,但它們對錶達式的*值*沒有任何影響。 – Pointy

5

有很多方法可以讓你在做什麼,嚴格來說這個話題的影響只有切關係倒閉的主題。

問題是這樣的:在JavaScript中,function關鍵字提供兩個不同的目的

  1. 它引入了一個函數聲明語句,這是一種,像一個var聲明(聲明變量)但對於一個功能;
  2. 它在更大的表達式的上下文中引入了函數文字表達式。

現在的問題是,當語法分析器在語句開頭看到function時,它假定你的意思是聲明一個函數;即上面的案例1。當你聲明一個函數時,你不能在同一個語句中調用它;函數聲明語句只是聲明瞭該函數。因此,如果你想要的是一個由只有組成的語句和它的直接調用,你必須把語法分析器解析一個表達式。把整個事情放在括號裏只是這樣做的一種方法。

任何「貓膩」是說服的是什麼它看到的是一個表達式語句會做解析器:

var dummy = function() { ... whatever ... }(); 

!function() { ... whatever ... }(); 

0 + function() { ... whatever ... }(); 

所有這些,以及其他無數的例子,做一些事情,比如當分析器看到function那關鍵字,它在表達式中間這樣做。

如果Mr.艾希選了一個不同的關鍵字的功能對象中期表達的實例(如拉姆達爲例),有好多是沒有問題的,因爲你可以接着剛纔說

lambda() { ... whatever ... }(); 

他沒有,然而。

1

其中任何一個的正確術語是立即執行的函數。

雖然這兩種工作方式相同,Douglas Crockford建議後者出於可讀性的原因。

當一個函數被立即調用,整個調用 表達應該被包裹在括號以便清楚的是正在生產的 值是功能而不是 函數本身的結果。

所以,如果你想採用這個建議,你應該更喜歡使用:

(function() { ... }()) 
0

前者更好,因爲它把功能作爲一個'一等公民」。它使用括號來包裝函數並調用它。

對於後者,它也避免語法不明確。

但我推薦前者。