2013-02-11 63 views
9

我在研究Immediatly調用函數表達式(IIFE)的行爲,並在做這件事時遇到以下情況。爲什麼這個分組操作符+函數立即調用

(function() { 
    document.write("bar"); 
}) 

(function() { 
    document.write("foo"); 
}()); 

我認爲第一個只是一個帶有函數表達式的分組操作符而沒有調用它。第二個是一個分組操作符以及一個函數表達式,但現在可以調用該函數。

我覺得奇怪的是,兩者都被調用,爲什麼?

(function() { 
    document.write("bar"); 
}) 

var x = 1; 

(function() { 
    document.write("foo"); 
}()); 

當我通過在兩者之間插入一個變量聲明來解決這兩個問題時,它只是寫入foo。這是我的預期。

+0

提示:使用http://www.jshint.com/ – elclanrs 2013-02-11 11:08:32

回答

15

因爲你忘了第一個函數表達式後分號:

(function() { 
    document.write("bar"); 
}); 

否則第二「分組運算符」被解釋爲一個函數調用。所以這個:

(function a() { 
    ... 
}) 

(function b() { 
    ... 
}()); 

是基本相同:

function b() { 
    ... 
} 

(function a() { 
    ... 
})(b()); 

重新排序使得它有點更容易看到。請記住,空白字符在JavaScript中沒有意義,並且被忽略。

+0

非常合理 - 謝謝 – 2013-02-11 11:54:26

4

正如Felix Kling正確指出的:缺少的分號會導致第二個IIFE周圍的括號被解釋爲函數調用,而不僅僅是對函數表達式進行分組。它變得更加清晰而不換行:

(function() { 
    document.write("bar"); 
})(function() { 
    document.write("foo"); 
}()); 

或者一些調整:

(function() { 
    document.write("bar"); 
})(
    function() { 
     document.write("foo"); 
    }() 
); 

第一個函數表達式稱爲與第二函數表達式作爲其第一個也是唯一一個參數的結果。您還應該注意,foobar是寫入而不是barfoo,因爲第二個函數被首先調用,並且其結果作爲參數傳遞給第一個函數。

3

你可以寫一個IIFE也是這樣的:(function() {})()

由於省略了分號,你的第一個codesnippet實際上是調用與移交作爲參數的第一第二IIFE第一功能。

    executing as parameter for the first IIFE 
               \/ 
(function() {document.write("bar");})((function() {document.write("foo");}());) 

其第一次印foo然後bar不像:

(function() { 
    document.write("bar"); 
})(); 

(function() { 
    document.write("foo"); 
}()); 

它打印barfoo

(function() { 
    document.write("bar"); 
}); 

(function() { 
    document.write("foo"); 
}()); 

其中第一現在僅視爲分組操作。

相關問題