当函数被包含在一堆括号()内部就称为了一个表达式,经过在末尾上加上另外一个()能够当即执行这个函数,这样的表达式就叫作当即执行函数表达式(Immediately Invoked Function Expression,简称IIFE),如:(function(){...})()或者(function(){...}())javascript
IIFE的另外一个很是广泛用法就是在外层括号传入参数进去,给内部的匿名韩式调用,来看下代码吧:java
var a = 2; (function(global){ var a = 3; console.log(a); //3 console.log(global.a); //2 })(window)
能够看到将window做为参数传入内部函数中,内部函数经过global.a访问到全局变量a编程
javascript支持函数式编程的,函数也能够做为对象传来传去,来看一段代码:闭包
(function IIFE(def){ def(window); })(function def(global){ var a = 3; console.log(a); //3 console.log(global.a); //2 });
再来看看当即执行函数和闭包应用的一个经典例子:异步
for(var i=0;i<5;i++){ setTimeout(function(){ console.log(i); },100) }
这段代码看起来是循环5次,间隔100ms打印出0,1,2,3,4,但实际上只会输出五次5,由于定时器是异步事件,异步事件只能在同步事件执行完后才能执行,也就是说定时器的回调在for循环完才执行,这里须要使用IIFE声明并当即执行函数来建立做用域,修改一下代码:函数式编程
for(var i=0;i<5;i++){ (function(i){ setTimeout(function(){ console.log(i); },100) })(i); }
在迭代里面使用IIFE会为每一个迭代都生成一个新的做用域,使得延迟函数的回调能够将新的做用域封闭在每一个迭代里,每一个迭代都会含有依着正确的值给咱们访问,记得实习第一天,老大给我出了个题,用原生js给5个li绑定点击事件,点击li弹出当前li的index,也是用这样的方法解决的。函数