zoukankan      html  css  js  c++  java
  • IIFE(立即执行函数表达式)

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

    ;(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 语句后应该加分号么?
  • 相关阅读:
    anaconda环境---ubuntu下重装
    算法---Face_Recognition配置实战篇
    算法---FaceNet+mtcnn的使用记录
    算法---FaceNet理论学习篇
    算法---FaceNet在Tf下的实战篇
    ubuntu系统---切换Py2.X与Py3.X版本
    anaconda环境中---py2.7下安装tf1.0 + py3.5下安装tf1.5
    Git---初入开源代码管理库的学习过程003
    day 87 Vue学习六之axios、vuex、脚手架中组件传值
    day 86 Vue学习之五DIY脚手架、webpack使用、vue-cli的使用、element-ui
  • 原文地址:https://www.cnblogs.com/liuyongjia/p/7896923.html
Copyright © 2011-2022 走看看