JavaScript立即执行函数(IIFE)

注:此文只在理解立即执行函数,文章大量引用立即调用的函数表达式
,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标准参考教程

你可能感兴趣的:(JavaScript立即执行函数(IIFE))