浅析js闭包
2019-03-11 09:45:29来源:博客园 阅读 ()
闭包是一个老生常谈的问题,简单概括下闭包的形成的两个条件:
1、定义在函数内部
2、函数内部引用父层作用域变量
举一个最简单的例子:
1 function test() { 2 var a = 1; 3 4 function hello() { 5 console.log(a); 6 } 7 return hello; 8 } 9 10 var world = test(); 11 world(); //1
以上代码会在控制台输出“1”。这是什么为什么呢?函数内部变量在调用结束后一般都会销毁,以上代码在test方法调用结束后并没有被销毁,这是由于js语言本身垃圾回收导致的。众所周知,js的垃圾回收机制是引用计数,当变量在其他作用域被引用时,该变量就不会被销毁,会一直存在内存中,这样就形成了闭包。在调试代码的过程中也可以在开发者工具中看出,如下图所示:
以上可以看出,当前环境存在一个作用域,Closure(text),包含引用父层的作用域的变量a。
js函数参数传递分为数值传递和引用传递,数值传递针对参数的类型为number/string/boolean....;引用传递针对参数类型为object/array....;所以在针对引用父层参数时,要注意父层参数类型,如果为数值传递,父层参数改变并不会影响闭包执行结果,但是如果参数是引用传递,要注意闭包里的参数引用的是父层变量地址,变量发生改变,闭包的执行结果会随之改变,以下代码可以看出:
1 var obj = { 2 num: { 3 b: 1 4 } 5 } 6 7 function test(obj) { 8 var a = obj.num; 9 10 function hello() { 11 console.log(a.b); 12 } 13 return hello; 14 } 15 16 var world = test(obj); 17 world(); //1 18 obj.num.b = 2; 19 test(obj); 20 world(); //2
执行结果:
再说一个经典的面试题:
1 for (var i = 0; i < 5; i++) { 2 setTimeout(function() { 3 console.log(i); 4 }, 0); 5 }
想必大家都知道这段代码的执行结果是5个1,但是有没有想过为什么会是5个1呢?
setTimeout函数比较特殊,其执行优先级要低于for循环,循环结束后才会被执行,其匿名函数类似于一个回调,匿名函数都引用了变量i,var声明的变量又不存在块级作用域,最终循环结束后,i值变为5,在回调执行过程中,会向父层作用域执行RHS查询(就是查找变量i的值是否存在),i的值目前存在于全局变量window中,但是已变成了5,所以会输出5个5。
如何让其一次性输入0,1,2,3,4呢?
其实问题的本源在于js语言中本来不存在块级作用域,for循环声明的变量i最终是在全局变量中,每次循环都会更新一次全局变量中的值,所以实现块级作用域有两种常用的方法,一是借助es6的声明变量的方法let,第二个是利用闭包;
闭包的代码如下:
1 for (var i = 0; i < 5; i++) { 2 setTimeout((function(i) { 3 console.log(i); 4 })(i), 0) 5 }
正如文章刚开始所述,setTimeout回调中引用的是父层函数中变量i的值,在每次声明的时候,都会将当前的i值传递给闭包,其有自己单独的作用域,不再是引用同一变量,具体作用域情况如下所示:
以上仅为个人看法,如有错误,烦请指出,谢谢!
原文链接:https://www.cnblogs.com/gerry2019/p/10507344.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- 浅析XMLHttpRequest的缓存问题 2020-02-25
- JavaScript闭包函数访问外部变量的方法 2019-12-24
- 函数作用域查找、闭包和匿名函数整理 2019-08-14
- 简单理解Javascript闭包 2019-08-14
- 浅析libuv源码-node事件轮询解析(3) 2019-05-13
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash