js 中的闭包问题
一、闭包到底是什么呢?
通俗地说,就是让外部可以访问函数内部变量,将函数外部与函数内部连接起来的桥梁。
而除此之外,闭包还有另一个特性:闭包会导致变量的值保存在内存中。
我们知道,函数内部声明的局部变量,只是一个暂时的变量,在它的作用域结束了之后它就会被垃圾回收销毁了。所以我们在外部想要调用它时,它已经死掉了,当然就是error未定义了。而闭包达到了怎样的目的呢?接下来可以看一个例子
function woman(){ var age=30; } alert(age);//wrong
由于函数外不能访问函数内的变量,输出就为wrong
function woman(){ var age=30; function happy(){ alert(age);//30 } }
函数内的方法可以访问age,所以输出为30
function woman(){ var age=30; function happy(){ alert(age); } } var cheat=woman(); cheat();//30
只要通过它来返回父对象的变量不就可以了嘛!这就可以解释第一个特性
关于第二个属性,请看下面的例子
for( var i = 0; i < 5; i++ ) { setTimeout(() => { console.log( i ); }, 1000) }
得到结果 5个5
setTimeout函数在当前执行队列的最后执行,获取到的i是最外部作用域的i=5,所以得到5个5
那么如果想1s后得到0-4怎么做?在for循环内创建闭包
for (var i = 0; i < 5; i++) { (function(j) { setTimeout(function() { console.log(j); },1000) })(i) }
同样setTimeout在执行队列的最后执行,获取到的j是外部函数的j,由于闭包中的变量会保存下来,每一次获取的j分别是0,1,2,3,4
二、使用闭包的注意点
使用闭包的一大注意点:由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
除了这个注意点,还有另外一点:
由于闭包调用函数内部变量,不是拷贝,而是引用,即,它是直接用了这个变量本身。所以说:
闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
参考文章:
https://blog.csdn.net/weixin_30391339/article/details/98802559
https://www.jianshu.com/p/121ff97c230f
浙公网安备 33010602011771号