JavaScript-- IIFE(立即调用函数)

IIFE:(立即调用函数)

IIFE( 立即调用函数表达式)是一个在定义时就会立即执行的 JavaScript 函数。

IIFE:全称为 Immediately-invoked function expression
其结构为:

(function(){/* code */}());//Crockford recommends this one,括号内的表达式代表函数立即调用表达式
(function(){/* code */})();//But this one works just as well,括号内的表达式代表函数表达式

特点: 立即调用函数中的匿名函数拥有拥有独立的词法作用域,其变量和方法等不能从外部访问。
好处: 使用立即调用函数不仅避免了外界访问此 IIFE 中的变量,而且又不会污染全局作用域,主要的作用是隔离作用域。

对于 IIFE 表达式中圆括号的理解:

在函数声明后加圆括号并不会立即调用,反而会报错,因为解析器会将圆括号默认为是对函数的声明。

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

//现在,你把一个表达式放在圆括号里,没有抛出错误...,但是函数也并没有执行,因为:

function foo(){/* code */}(1)

//它等同于如下,一个函数声明跟着一个完全没有关系的表达式:

function foo(){/* code */}
(1);
  • 当圆括号出现在匿名函数的末尾想要调用函数时,它会默认将函数当成是函数声明。
  • 当圆括号包裹函数时,它会默认将函数作为表达式去解析,而不是函数声明。

这样的括号指明函数表达式将会被立即调用,并且变量将会储存函数的结果,而不是函数本身。当这是一个非常长的函数表达式时,这可以节约比人阅读你代码的时间,不用滚到页面底部去看这个函数是否被调用。

立即调用函数的使用

  • 可以保存闭包的状态
  • 向外暴露一个全局函数(如 jQuery的封装)
  • 立即执行,方便查看函数的调用状态

保存闭包的状态:

看下面例子中,因为 for 循环中 var 声明的变量 i 为全局作用域,循环结束当触发 onclick 事件时 i 保存的是当前最新的值,所以想要触发时显示的都是6.

        var liList = ul.getElementsByTagName('li')
        for(var i=0; i<6; i++){
          liList[i].onclick = function(){
            alert(i) // 为什么 alert 出来的总是 6,而不是 0、1、2、3、4、5
          }
        }

可以使用立即调用函数来隔离作用域,保存每层循环中 i 的值,相当于循环一次就执行一次函数创建了一个新的变量 ii 来保存值。

var liList = ul.getElementsByTagName('li')
for(var i=0; i<6; i++){
  function(ii){
    liList[ii].onclick = function(){
      alert(ii) // 0、1、2、3、4、5
    }
  }(i)
}

es6 中可以使用 let 来解决这个问题,更加方便,因为 let 声明的变量是在块级作用域中,外部访问不到,相当于每层循环中块级作用域内都有一个变量用来保存 i 的值。let 在 for 循环中具体怎么实现的可以参考以下文章:

向外暴露一个全局函数,可以进行模块化:
如下面例子中,新建一个 myModule.js 实现字母大小写的转换,将方法写在一个立即调用函数中,并向外暴露一个全局对象,方便js模块的管理和使用。
index.html

<script src="myModule.js"></script>
    <script>
        /**/
      myModule.upperCase('bjt')
      myModule.lowerCase('BJT')
    </script>

myModule.js

;(function () {
   function upperCase(msg) {
       console.log(msg+'转换为大写字母:'+msg.toUpperCase())
   }
   function lowerCase(msg) {
       console.log(msg+'转换为小写字母:'+msg.toLowerCase())
   }
   //以对象的形式暴露一个全局变量
   window.myModule={
       upperCase:upperCase,
       lowerCase:lowerCase
   }
})()

运行结果:
bjt转换为大写字母:BJT
myModule.js:6 BJT转换为小写字母:bjt

分号的理解

立即调用函数前最好加;分号,避免 js文件合并压缩时代码执行解析出现错误。

参考文档:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值