一弄JS,就总有人在提闭包、闭包的,此前不了解,上网上搜,很多讲的也过于难懂,感觉没有必要那么复杂,今天就把我对于闭包的理解总结一下,力求简单、通俗、易懂
目录
1.什么是闭包
通俗的理解就是:子函数使用着父函数作用域内的变量,导致父函数作用域内的变量无法回收释放的这种情况。
-
<script>
-
function a(){
-
let num=
0;
-
return
()=>{
-
console.log(num++);
-
}
-
};
-
let t=a();
-
//执行三次结果是多少?
-
t();
-
t();
-
t();
-
</script>
看上面的代码,分别执行三次t(),那么结果是多少呢?
结果是0,1,2,这是怎么回事呢?原因就是闭包导致的。
我们首先分析:a函数内有一个num变量和一个子函数,在子函数中使用着父函数a的变量num,使其自加1。随后将a函数执行后复制给t,由于子函数一直在使用num变量(其实不论子函数是否使用,父函数的变量都不会释放,随时等待子函数调用除非子函数引用被释放),所以num变量并不会回收释放。也就是说三次t()改变的num其实是一个。这就是闭包的原因,如果没有闭包,在子函数处理完num后,num回收,则应该是三个0。
2.闭包有什么用?
从另一个角度理解,如果一个函数没有被回收释放,那么他的父级、父级的父级。。。。。祖宗级(全局)的变量也不会被释放,而且可以被函数访问到。这就是为什么全局变量在哪里都可以访问的原因了,其实就是闭包的应用。那什么时候全局变量不可用了呢,就是他内部的子函数引用都被清空的时候,也就是程序关闭了,网页关闭了之后。
1.绝大多数时候我们不会有意识的用到闭包,但是没有闭包你得程序是跑不了的,比如全局变量。。。。。
2.极少数情况下我们用函数去给一个变量“续命”。这种情况下,闭包就会被用到了。
3.还有就是,如果问你:
JS中没有严格意义的私有变量,请问你能弄出来绝对私有么?答案:能。请看代码:
-
<script>
-
//这个num就是真的严格意义的私有
-
let a=(
function (){
-
let num =
0;
-
return {
-
get(){
-
return num;
-
},
-
set(val){
-
num=val;
-
}
-
}
-
})();
-
a.set(
55);
-
console.log(a.get());
-
</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