注:此文只在理解立即执行函数,文章大量引用立即调用的函数表达式
,javascript立即执行某个函数:插件中function(){}()再思考,MDN的JavaScript 参考文档,阮一峰的JavaScript标准参考教程的内容
简介
有时,我们需要在定义函数之后,立即调用该函数。于是就有了IIFE这种说法
立即执行函数通常有以下的写法:
(function(){ /*code*/ })();
(function(){ /*code*/ }());
在Javascript中,一对圆括号“()”是一种运算符,跟在函数名之后,表示调用该函数,如alert()这时,如果你在函数的定义之后加上圆括号,这会产生语法错误。
function(){ /*code*/ }();
function name(){ /*code*/ }();
//SyntaxError: Unexpected token (
产生这个错误的原因是,function这个关键字即可以当作语句,也可以当作表达式。
// 语句
function f() {}
// 表达式
var f = function f() {}
为避免出现上面的歧义,JavaScript 引擎规定,如果function关键字出现在行首,一律解释成语句。
解决的办法是不要让function出现在行首,让引擎将其理解成一个表达式。
(function(){ /* code */ }());
// 或者
(function(){ /* code */ })();
上面两种写法都是以圆括号开头,引擎就会认为后面跟的是一个表示式,而不是函数定义语句,所以就避免了错误。
推而广之,任何让解释器以表达式来处理函数定义的方法,都能产生同样的效果,比如下面三种写法。
var i = function(){ return 10; }();
true && function(){ /* code */ }();
0, function(){ /* code */ }();
甚至像这样写:
!function(){ /* code */ }();
~function(){ /* code */ }();
-function(){ /* code */ }();
+function(){ /* code */ }();
何时使用
通常情况下,只对匿名函数使用这种“立即执行的函数表达式”。
它的目的有两个:
- 一是不必为函数命名,避免了污染全局变量;
- 二是IIFE内部形成了一个单独的作用域,可以封装一些外部无法读取的私有变量。
// 写法一
var tmp = newData;
processData(tmp);
storeData(tmp);
// 写法二
(function () {
var tmp = newData;
processData(tmp);
storeData(tmp);
}());
上面代码中,写法二比写法一更好,因为完全避免了污染全局变量。
参考
立即调用的函数表达式
javascript立即执行某个函数:插件中function(){}()再思考
MDN的JavaScript 参考文档
阮一峰的JavaScript标准参考教程
网友评论