IIFE—立即调用的函数表达式(Immediately Invoked Function Expression)

 IIFE类似于函数声明,但由于被包含在括号中,所以会被解释为函数表达式。紧跟在第一组括号后面的第二组括号会立即调用前面的函数表达式。

1 (function() {
2     // 块级作用域
3 })()

 使用IIFE可以模拟块级作用域,即在一个函数表达式内部声明变量,然后立即调用这个函数。ES5没有支持块级作用域,使用IIFE模拟块级作用域是相当普遍的。

1 // IIFE 
2 (function () { 
3  for (var i = 0; i < count; i++) { 
4  console.log(i); 
5  } 
6 })(); 
7 console.log(i); // 抛出错误
前面的代码在执行到 IIFE 外部的 console.log()时会出错,因为它访问的变量是在 IIFE 内部定义的,在外部访问不到。
  ECMAScript 5.1 及以前,为了防止变量定义外泄,IIFE 是个非常有效的方式。这样也不会导致闭包相关的内存问题,因为不存在对这个匿名函数的引用。为此,只要函数执行完毕,其作用域链就可以被销毁。
  在ES6以后,IIFE就没有那么必要了,因为块级作用域中的变量无需IIFE就可以实现同样的隔离
 1 // 内嵌块级作用域 
 2 { 
 3  let i; 
 4  for (i = 0; i < count; i++) { 
 5  console.log(i); 
 6  } 
 7 } 
 8 console.log(i); // 抛出错误
 9 // 循环的块级作用域
10 for (let i = 0; i < count; i++) { 
11  console.log(i); 
12 } 
13 console.log(i); // 抛出错误

说明IIFE作用的一个实际的例子,就是可以用它锁定参数值。比如:

1 let divs = document.querySelectorAll('div'); 
2 // 达不到目的! 
3 for (var i = 0; i < divs.length; ++i) { 
4  divs[i].addEventListener('click', function() { 
5  console.log(i); 
6  }); 
7 }

这里使用var关键字声明了迭代变量i,这里的i在循环结束以后,将会编程循环结束时的最终值。因为这个变量i是全局的,外部随时可以访问。可以借助IIFE来执行一个函数表达式,传入每次循环的当前索引,从而达到“锁定”点击时的索引值。

1 let divs = document.querySelectorAll('div'); 
2 for (var i = 0; i < divs.length; ++i) { 
3  divs[i].addEventListener('click', (function(frozenCounter) {
4  return function() { 
5  console.log(frozenCounter); 
6  }; 
7  })(i)); 
8 }

这里使用let声明i也可以达到同样的目的

原文地址:https://www.cnblogs.com/codexlx/p/14336098.html