• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
cc7777
博客园    首页    新随笔    联系   管理    订阅  订阅

立即调用的函数表达式(IIFE)

在JavaScript中,圆括号 () 是一种运算符,跟在函数名之后,表示调用该函数。比如, print() 就表示调用 print 函数。

有时,我们需要在定义行数之后,立即调用该函数。这时,你不能在函数的定义之后加上圆括号,这会产生语法错误。

function(){/* code */};
// SyntaxError: Unexpected token (

产生这个错误的原因是, function 这个关键字即可以当做语句,也可以当作表达式。

//语句
function f(){}

//表达式
var  f = function f(){}

为了避免解析上的歧义,JavaScript引擎规定,如果 function 关键字出现在首行,一律解析成语句。因此,JavaScript引擎看到行首是 function 关键字之后,认为这一段都是函数的定义,不应该以圆括号结尾,所以就报错了。

解决方法就是不要让 function 出现在行首,让引擎将其理解成一个表达式。最简单的处理,就是将其放在一个圆括号里面。

(function(){ / * code */ }());
//或者
(function(){ /* code */ })();

上面两种写法都是以圆括号开头,引擎就会认为后面跟的是一个表达式,而不是函数定义语句,所以就避免了错误。这就叫做“立即调用的函数表达式”(Immediately-Invoked Function Expression),简称IIFE。

注意,上面两种写法最后的分号都是必须的。如果省略分号,遇到连着的两个IIFE,可能就会报错。

//报错
(function(){ /* code */}())
(function(){ /* code */}())

上面代码的两行之间没有分号,JavaScript会将它们连在一起解释,将第二行解释为第一行的参数。

推而广之,任何让解释器以表达式来处理函数定义的方法,都能产生同样的效果,比如下面三种写法。

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);
}());

上面代码中,写法二比写法一更好,因为完全避免了污染全局变量。

 

转自:https://wangdoc.com/javascript/types/function.html#%E7%AB%8B%E5%8D%B3%E8%B0%83%E7%94%A8%E7%9A%84%E5%87%BD%E6%95%B0%E8%A1%A8%E8%BE%BE%E5%BC%8F%EF%BC%88iife%EF%BC%89

posted @ 2018-09-12 18:07  cc7777  阅读(422)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3