立即执行函数-转

83 阅读2分钟

立即调用的函数表达式-IIFE

立即执行函数有两种写法:

  • (function(){})() 匿名函数包裹在一个括号运算符中,后面再跟一个小括号
  • (function(){}()) 匿名函数后面跟一个小括号,然后整个包裹在一个括号运算符中

上述两种写法是等价的,要想立即执行函数做到立即执行,要注意两点:

  • 函数体后面要有小括号
  • 函数体必须是函数表达式而不能是函数声明

立即执行函数的作用是:

  • 1.创建一个独立的作用域,这个作用域里面的变量,外面访问不到,这样就可以避免变量污染。
(function() { 
  // 块级作用域 
  for (var i = 0; i < 5; i++) { 
    console.log(i); 
  } 
})(); 
console.log(i); 

上述代码中当解析到console.log(i);时,会报错ReferenceError: i is not defined,这是因为它访问的变量是在IIFE内部定义的,在外部访问不到。

在es5以前,为了防止变量定义外泄,IIFE是个非常有效的方式,这样也不会导致闭包相关的内存问题,因为不存在对这个匿名函数的引用。 因此,只要函数执行完毕,其作用域链就可以被销毁。

  • 2.闭包和私有数据。提到闭包,不得不提下那道经典的闭包问题。
<script>
    var liList=document.getElementsByTagName('li');
    for(var i=0;i<liList.length;i++)
    {
        (function(ii) {
           liList[ii].onclick=function(){
               console.log(ii);
           }
       })(i)
    };
</script>

实现私有变量

IIFE可以返回一个函数引用,当这个函数在IIFE的词法范围外执行,也会创建一个闭包,使函数能够访问局部变量。

const getOrderId = (function() { 
  let count = 0; 
  return function() { 
    ++count; 
    return `id_${count}`; 
  }; 
})(); 
console.log(getOrderId()); 
console.log(getOrderId()); 
console.log(getOrderId()); 
console.log(getOrderId()); 

上述代码中:

  • 创建了一个自执行函数,其返回一个函数引用
  • 自执行函数内部有一个变量count,它就是一个私有变量,外部无法访问
  • 最后,返回一个函数引用,形成闭包结构,对count自增后与_id进行拼接并返回

在IIFE之外无法访问函数内部的count变量,除了从IIFE中返回的函数,别处无法读写该变量,这样就能创建真正的私有状态变量。