再谈javascript闭包

晚上无聊,刚刚看完高程的闭包。感觉不知不觉离上次看闭包已经过去四个月。。。今天再次总结下- -

上一篇总结地址:javascript闭包

什么是闭包

我的理解就是:子作用域读取父作用域中的变量。


简单来说就是:javascript中有个很特别的地方。局部作用域可以访问全局作用域,但是全局作用域不能访问局部作用域的值,如果想要访问。就只能通过闭包啦。

一道经典的例子

不明白?那就先来看看这个例子

1
2
3
4
5
for(var a=0;a<3;a++){
setTimeout(function(){
console.log("zone")
},0)
}

当在chrome浏览器中运行的时候,我们发现结果并不是我期望的0,1,2而是:
0_1476462430017_upload-097da577-e6c5-4073-8260-35c1112df4fb

这里的原因主要是:setTimeout读取a是动态读取的。当我读取的时候,其实此时for循环已经结束了,全局的a已经变成3。

解决办法:

闭包解决。

这里就需要用到闭包来解决问题。

1
2
3
4
5
for(var a=0;a<3;a++){
(function(num){(setTimeout(function(){
console.log("zone")
},0)})(i)
}

0_1476462390980_upload-b3466ac0-047c-4bfd-8d9d-f0c85928bc3c
这里其实也就是为每个闭包单独创建了一个作用域。把a给保存了下来。

bind解决

其实除了 上面那种 还有js值的传递和利用闭包读取到父级作用域的集合,然后在集合中寻找自己不过突然发现前几个月已经用这种方法实现过了- -


不过现在又有了一种新的方法

1
2
3
for(var a=0;a<3;a++){
setTimeout(console.log.bind(null,a),0)
}

0_1476463245753_upload-67b4da20-ebc3-4aa4-b172-0d4bf91294aa
这里就相当于强制绑定参数a。其实和利用闭包构建方法类似,不过我感觉在实际工作中貌似bind会更加好用。毕竟这样比较cool

关于bind的具体用法 直接看MDN文档吧。bind的具体用法


今天周六。上完班就休息啦0.0