当函数被包含在一堆括号()内部就称为了一个表达式,通过在末尾上加上另一个()可以立即执行这个函数,这样的表达式就叫做立即执行函数表达式(Immediately Invoked Function Expression,简称IIFE),如:(function(){...})()或者(function(){...}())
IIFE的另一个非常普遍用法就是在外层括号传入参数进去,给内部的匿名韩式调用,来看下代码吧:
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,也是用这样的方法解决的。
时间: 2024-12-26 19:35:27