我们经常会看到这样的写法:

;(fuction () {
// do something
})()

这就是一个简单的IIFE(立即执行函数表达式,immediately-invoked function expression)了。

这样的写法有什么好处呢?来简单分析一下。

1. 开头的分号

我们都知道,js是可以加分号或者不加分号的,在某些情况下,不加分号会让解析器解析出错,举个例子:

var
a = 0
, b = 0
;
a = b + 3
(b = a)
// Uncaught TypeError: 3 is not a function

解析代码的时候,a = b + 3和(b = a)这两条语句之间没有明确的分界,回车和空格会自动被忽略。解析器会认为这是一句。所以,此时会认为3是一个函数,b=a是他的参数。

在知乎的这个问题下,尤大做了解释。

真正会导致上下行解析出问题的 token 有 5 个:括号,方括号,正则开头的斜杠,加号,减号。我还从没见过实际代码中用正则、加号、减号作为行首的情况,所以总结下来就是一句话:一行开头是括号或者方括号的时候加上分号就可以了,其他时候全部不需要。其实即使是这两种情况,在实际代码中也颇为少见。

ok,回到我们的例子,我们的例子就是以括号开头的,如果上一个语句没有加分号,很可能会出现这样问题,这个分号就是为了防止这样的情况发生,称之为防御性分号。

2. function(){}

函数有两种声明方式:

function foo () {}
var foo = function () {}

这两种声明方式的不同之处在于,使用var声明的函数不会自动提升到顶部。也就是说,不能在var声明函数的语句之前调用函数,否则会抛出undefined的错误。

function () {}这种形式被称为匿名函数。匿名函数没有名字,也就是没有指针,是无法在其他地方调用的。

将匿名函数赋值给foo,则可以通过foo来调用。

当然还有办法调用它,就是例子中的两对括号。第一对括号将匿名函数包装成了一个表达式,而第二对括号意思就是立即执行它。

function () {console.log('a')} // 报错 Uncaught SyntaxError: Unexpected token (
(function () {console.log('a')}) // 返回函数定义 ƒ () {console.log('a')},没有log
(function () {console.log('a')})() // a
function foo() {console.log('a')}() // 报错 Uncaught SyntaxError: Unexpected token )

第一行,因为不是合法的声明方式,希望找到函数名的地方是‘(’,所以抛出了该异常。

第二行,()中的语句被当成了表达式,解析器会认为是var声明的方式。

第三行,自执行。

第四行,function foo() {console.log('a')}是正确的函数声明方式,被正确解析。接下来的一对括号依次解析,括号里需要有表达式,但是没有,所以会抛出这样的异常。

3. 好处

IIFE的好处就是不会污染全局变量,就在当前的函数体的作用域下进行操作,保证了父作用域的干净,如果return出一些函数,那这些函数就形成了闭包。

我们常用IIFE来写module。

var counter = (function(){
var i = 0; return {
get: function(){
return i;
},
set: function( val ){
i = val;
},
increment: function() {
return ++i;
}
};
})()

Refer:

  1. 维基百科:立即调用函数表达式
  2. 知乎:JavaScript 语句后应该加分号么?

IIFE(立即执行函数表达式)的更多相关文章

  1. IIFE 立即执行函数表达式-模块化

    1)立即执行 2)表达式 3)括号,分号结束 | 前缀运算符 | 表达式上下文 4)只需要执行一次,内部变量无需维护,可用于初始化 (function( ) { })( ); 或 (function( ...

  2. 立即执行函数表达式(IIFE)

    原文地址:benalman.com/news/2010/11/immediately-invoked-function-expression/ 译者:nzbin 也许你还没有注意到,我是一个对术语比较 ...

  3. (译)详解javascript立即执行函数表达式(IIFE)

    写在前面 这是一篇译文,原文:Immediately-Invoked Function Expression (IIFE) 原文是一篇很经典的讲解IIFE的文章,很适合收藏.本文虽然是译文,但是直译的 ...

  4. JS立即执行函数表达式(IIFE)

    原文为 http://benalman.com/news/2010/11/immediately-invoked-function-expression/#iife ----------------- ...

  5. 【JavaScript】浅析IIFE(立即执行函数表达式)的作用

    什么是IIFE IIFE就是立即执行函数表达式(Immediately-Invoked Function Expression) 为什么需要IIFE 应用IIFE有两个比较经典的使用场景, 第一就是在 ...

  6. 详解javascript立即执行函数表达式(IIFE)

    立即执行函数,就是在定义函数的时候直接执行,这里不是申明函数而是一个函数表达式 1.问题 在javascript中,每一个函数在被调用的时候都会创建一个执行上下文,在函数内部定义的变量和函数只能在该函 ...

  7. [转]Javascript中的自执行函数表达式

    [转]Javascript中的自执行函数表达式 本文转载自:http://www.ghugo.com/javascript-auto-run-function/ 以下是正文: Posted on 20 ...

  8. IIFF(立即执行函数表达式)

    立即执行函数表达式(Immediately-invoked function expression,IIFF) 在javascript(ES5)中,是没有块级作用域的概念的 for (var i = ...

  9. 【JavaScript专题】--- 立即执行函数表达式

    一 什么是立即执行函数表达式 立即执行函数表达式,其实也可以叫初始化函数表达式,英文名:IIFE,immediately-inovked-function expression.立即执行函数表达式就是 ...

随机推荐

  1. 微信小程序城市定位(借助百度地图API判断城市)

    概述 微信小程序提供一些API(地址)用于获取当前用户的地理位置等信息,但无论是wx.getLocation,还是wx.chooseLocation均没有单独的字段表示国家与城市信息,仅有经纬度信息. ...

  2. [js插件开发教程]实现一个比较完整的开源级选项卡插件

    在这篇文章中,我实现了一个基本的选项卡功能:请猛击后面的链接>>   [js插件开发教程]原生js仿jquery架构扩展开发选项卡插件. 还缺少两个常用的切换(自动切换与透明度渐变),当然 ...

  3. APP在模拟器崩溃,提示__gcd_queue_item_enqueue_hook_block_invoke

    libBacktraceRecording.dylib`__gcd_queue_item_enqueue_hook_block_invoke: libBacktraceRecording.dylib` ...

  4. Docker部属Nsq集群

    用一了段时间NSQ还是很稳定的.除了稳定,还有一个特别值的说的就是部署非常简单.总想写点什么推荐给大家使用nsq来做一些东西.但是就是因为他太简单易用,文档也比较简单易懂.一直不知道要写啥!!!!! ...

  5. iOS 通讯录空格

    iOS 通讯录联系人出现 ASCII 码值为 160 的空格  NOTE:       这里的"空格"是指 在通讯录中取出的联系人中带有特殊空格 带有特殊空格的字符串 " ...

  6. Yii2之ListView小部件

    ListView是yii框架中类似GridView,也是用于展示多条数据的小部件,相比GridView,ListView可以更加灵活地设置数据展示的格式. 下面以我自己做的一个使用ListView来展 ...

  7. Mac下如何安装JDK

    1.访问Oracle官网 http://www.oracle.com,浏览到首页的底部菜单 ,然后按下图提示操作: 2.点击"JDK DOWNLOAD"按钮: 3.选择" ...

  8. spring boot 自己输出json数据

    @RequestMapping("/json")public void json(HttpServletResponse response, Pager pager, TruckF ...

  9. poj 3662 Telephone Lines

    Telephone Lines Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7115   Accepted: 2603 D ...

  10. Fibonacci(...刷的前几道题没有记博客的习惯,吃了大亏)

    Fibonacci Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...