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

posted on 2021-03-16 13:34  代码老丸子  阅读(140)  评论(1)    收藏  举报

导航