记得刚学习js的时候,第一次听说闭包也是云里雾里。不知道今天为嘛心血来潮想要写一篇闭包啊,好吧,不装逼了,干正事。
闭包是有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式是,在一个函数内部创建另一个函数,当前作用域总是能够访问外部作用域中的变量。
首先,先看看下面代码:
for (var i=0;i<10;i++){
setTimeout(function(){
console.log(i);
},1000);
}
输入啥?
别以为他会输入0-9,其实是输出10。原因是当 console.log 被调用的时候,匿名函数保持对外部变量 i 的引用,此时 for循环已经结束, i 的值被修改成了 10。
那有啥解决办法呢,可以用立即执行函数来解决。
method1:
for (var i=0;i<10;i++){
(function(e){
setTimeout(function(){
console.log(e);
},1000);
})(i);
}
外部的匿名函数会立即执行,并把 i 作为它的参数,此时函数内 e 变量就拥有了 i 的一个拷贝。当传递给 setTimeout 的匿名函数执行时,它就拥有了对 e 的引用,而这个值是不会被循环改变的。嗯,所以会输入0-9。
method 2:
for (var i=0;i<10;i++){
setTimeout((function (e) {
return function () {
console.log(e);
}
})(i),1000);
}
这个是从匿名包装器中返回一个函数。
上面三个code片段的结果是这个:
网上我比较喜欢的闭包教程:
学习Javascript闭包(Closure)
javascript中闭包的工作原理