博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
再谈Js闭包
阅读量:7058 次
发布时间:2019-06-28

本文共 1083 字,大约阅读时间需要 3 分钟。

不知不觉距离上一篇闭包文章已经过了8个月了,现在的理解对比之前要健壮的多,再次总结下花生理解的闭包。

闭包实际上就是子作用域读取父作用域的变量,这本来很合理也很简单,但是关键点在于这个读取是动态的,请看下面的例子:

for(var i=0 ;i<3 ;i++){    setTimeout(function(){        console.log(i);    });};// 输出 3 3 3

结果并不是期望的0 1 2,因为是动态的读取i,因此如果你在下文改变变量i也依旧会影响到输出读取i。

传统的解决方案是构建闭包,是最有效也是兼容性最好的方法

for(var i=0 ;i<3 ;i++){    (function(num){        setTimeout(function(){            console.log(num);        });    })(i);};// 输出 0 1 2

这么做是十分有效的,为每一个闭包单独创建一个作用域,也是下面要说的其他解决方案的基础。

这一段代码很重要,理解这一段代码基本上就可以说理解闭包了。

实际上,大多数情况我们并不是想单纯是使用for循环,for循环的一个很常见的用处是遍历数组。

var arr =['a' ,'b' ,'c'];for(var i=0 ;i

因为是动态读取,所以输出undefined很正常。可以使用上面的构建一个自执行函数来解决,但还有一个更方便的解决方案,也是实际开发中经常用到的。

['a' ,'b' ,'c'].forEach(function(item){    setTimeout(function(){        console.log(item);    });});// 输出 a b c

利用Array原生的forEach可以更好的实现,而且也符合语义,这个是花生最推荐的用法。

如果浏览器较新支持ES5,Function还提供一个bind方法来绑定参数

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

Function.bind具体的语法与兼容性可以参考。

还有其他的“歪门邪道”的解决方案,比如利用闭包读取到父作用域的集合,在集合里寻找“自己”,或者是利用js的引用传递等等。

实际上,利用ES5的bind方法和Array的forEach就已经可以解决所有问题了,所以在实际开发中应该避免第一种构建闭包的解决方案。

转载地址:http://smgol.baihongyu.com/

你可能感兴趣的文章
C#身份证识别相关技术
查看>>
【单片机】基于有方GPRS的智能电梯控制系统
查看>>
基于spring-boot的rest微服务框架
查看>>
微信公众平台开发最佳实践(第2版)
查看>>
Maven 依赖 spring-web 对战 spring-webmvc
查看>>
用了一天的时间,linux下expect实现ssh自动登录服务器记,鄙视下网上各种抄来抄去残段子...
查看>>
青岛市李沧区搭建人才大数据平台
查看>>
Linux下自动化监控内存、存储空间!
查看>>
iOS 7 表视图顶部空白解决
查看>>
中科院院士姚期智:我们已经来到量子时代的最后一里路
查看>>
“前.NET Core时代”如何实现跨平台代码重用 ——程序集重用
查看>>
一哄而起云计算(透视)
查看>>
如何实现对上下文(Context)数据的统一管理 [提供源代码下载]
查看>>
RvmTranslator Translate RVM to 3D PDF
查看>>
New Release: patterns & practices App Arch Guide 2.0 Beta 1
查看>>
服务企业互联网化用友进入3.0时代
查看>>
Fortinet FortiGuard安全实验室解密APT攻击的那些事儿
查看>>
用友云重装出发:你想得到的企业服务都在这
查看>>
经典网络的ECS实例支持升级到企业级实例
查看>>
定位与大数据邂逅,Wi-Fi大不相同
查看>>