注:此文只在理解立即執(zhí)行函數(shù),文章大量引用立即調(diào)用的函數(shù)表達式
,javascript立即執(zhí)行某個函數(shù):插件中function(){}()再思考,MDN的JavaScript 參考文檔,阮一峰的JavaScript標準參考教程的內(nèi)容
簡介
有時,我們需要在定義函數(shù)之后,立即調(diào)用該函數(shù)。于是就有了IIFE這種說法
立即執(zhí)行函數(shù)通常有以下的寫法:
(function(){ /*code*/ })();
(function(){ /*code*/ }());
在Javascript中,一對圓括號“()”是一種運算符,跟在函數(shù)名之后,表示調(diào)用該函數(shù),如alert()這時,如果你在函數(shù)的定義之后加上圓括號,這會產(chǎn)生語法錯誤。
function(){ /*code*/ }();
function name(){ /*code*/ }();
//SyntaxError: Unexpected token (
產(chǎn)生這個錯誤的原因是,function這個關鍵字即可以當作語句,也可以當作表達式。
// 語句
function f() {}
// 表達式
var f = function f() {}
為避免出現(xiàn)上面的歧義,JavaScript 引擎規(guī)定,如果function關鍵字出現(xiàn)在行首,一律解釋成語句。
解決的辦法是不要讓function出現(xiàn)在行首,讓引擎將其理解成一個表達式。
(function(){ /* code */ }());
// 或者
(function(){ /* code */ })();
上面兩種寫法都是以圓括號開頭,引擎就會認為后面跟的是一個表示式,而不是函數(shù)定義語句,所以就避免了錯誤。
推而廣之,任何讓解釋器以表達式來處理函數(shù)定義的方法,都能產(chǎn)生同樣的效果,比如下面三種寫法。
var i = function(){ return 10; }();
true && function(){ /* code */ }();
0, function(){ /* code */ }();
甚至像這樣寫:
!function(){ /* code */ }();
~function(){ /* code */ }();
-function(){ /* code */ }();
+function(){ /* code */ }();
何時使用
通常情況下,只對匿名函數(shù)使用這種“立即執(zhí)行的函數(shù)表達式”。
它的目的有兩個:
- 一是不必為函數(shù)命名,避免了污染全局變量;
- 二是IIFE內(nèi)部形成了一個單獨的作用域,可以封裝一些外部無法讀取的私有變量。
// 寫法一
var tmp = newData;
processData(tmp);
storeData(tmp);
// 寫法二
(function () {
var tmp = newData;
processData(tmp);
storeData(tmp);
}());
上面代碼中,寫法二比寫法一更好,因為完全避免了污染全局變量。
參考
立即調(diào)用的函數(shù)表達式
javascript立即執(zhí)行某個函數(shù):插件中function(){}()再思考
MDN的JavaScript 參考文檔
阮一峰的JavaScript標準參考教程