飞道的博客

闭包--没有那么复杂!

223人阅读  评论(0)

一弄JS,就总有人在提闭包、闭包的,此前不了解,上网上搜,很多讲的也过于难懂,感觉没有必要那么复杂,今天就把我对于闭包的理解总结一下,力求简单、通俗、易懂


目录

1.什么是闭包

2.闭包有什么用?

3.闭包带来了什么问题呢?

4.总结


 1.什么是闭包

通俗的理解就是:子函数使用着父函数作用域内的变量,导致父函数作用域内的变量无法回收释放的这种情况。


  
  1. <script>
  2. function a(){
  3. let num= 0;
  4. return ()=>{
  5. console.log(num++);
  6. }
  7. };
  8. let t=a();
  9. //执行三次结果是多少?
  10. t();
  11. t();
  12. t();
  13. </script>

 看上面的代码,分别执行三次t(),那么结果是多少呢?

结果是0,1,2,这是怎么回事呢?原因就是闭包导致的。

我们首先分析:a函数内有一个num变量和一个子函数,在子函数中使用着父函数a的变量num,使其自加1。随后将a函数执行后复制给t,由于子函数一直在使用num变量(其实不论子函数是否使用,父函数的变量都不会释放,随时等待子函数调用除非子函数引用被释放),所以num变量并不会回收释放。也就是说三次t()改变的num其实是一个。这就是闭包的原因,如果没有闭包,在子函数处理完num后,num回收,则应该是三个0。

2.闭包有什么用?

从另一个角度理解,如果一个函数没有被回收释放,那么他的父级、父级的父级。。。。。祖宗级(全局)的变量也不会被释放,而且可以被函数访问到。这就是为什么全局变量在哪里都可以访问的原因了,其实就是闭包的应用。那什么时候全局变量不可用了呢,就是他内部的子函数引用都被清空的时候,也就是程序关闭了,网页关闭了之后。

1.绝大多数时候我们不会有意识的用到闭包,但是没有闭包你得程序是跑不了的,比如全局变量。。。。。

2.极少数情况下我们用函数去给一个变量“续命”。这种情况下,闭包就会被用到了。

3.还有就是,如果问你:

JS中没有严格意义的私有变量,请问你能弄出来绝对私有么?答案:能。请看代码:


  
  1. <script>
  2. //这个num就是真的严格意义的私有
  3. let a=( function (){
  4. let num = 0;
  5. return {
  6. get(){
  7. return num;
  8. },
  9. set(val){
  10. num=val;
  11. }
  12. }
  13. })();
  14. a.set( 55);
  15. console.log(a.get());
  16. </script>

这时a将返回一个json,里面有两个函数,分别是get和set。当你在外部给num赋值或者是调用num时,必须通过get和set“属性访问器”去访问,否则无法访问到num变量(真正的私有)。因为当你不用get和set时候也就是说get和set函数是不存在的,那么根据“闭包的原理”num会被释放掉,也就是说num不存在了,所以你直接num赋值是undefined的。

3.闭包带来了什么问题呢?

这里最为典型的就是for循环中用var定义循环变量(var i=0;i<10;i++),循环的结果是相同的,就是最后一次运算的结果。这里就涉及到了作用域和闭包的问题。详细的请看我的这篇文章,本文就不赘述了。

深入理解js_for循环条件中使用var为什么会出问题?(js块级作用域理解)

4.总结

相信大家看完之后一定会明白闭包是咋回事,这就是我目前理解道德闭包。当然如果有更好的补充,十分欢迎大家留言讨论。


转载:https://blog.csdn.net/qq_42539194/article/details/115866021
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场