美文网首页
js 闭包(面试题)

js 闭包(面试题)

作者: 洪锦一 | 来源:发表于2021-10-13 10:53 被阅读0次

    我们首先知道闭包有3个特性:
    ①函数嵌套函数
    ②闭包就是能够读取其他函数内部变量的函数
    ③参数和变量不会被垃圾回收机制回收

    1. 闭包的本质就是在一个函数内部创建另一个函数。

    function fn() {
        var name = "zs"
        return function () {
            return name;
        }
    }
    var fnn = fn();
    console.log(fnn());//zs
    

    2

    function fun() {
        var num = 3;
        return function () {//匿名函数
            var n = 0;
            console.log(++n);
            console.log(++num);
        }
    }
    var f = fun();
    f()//1 4
    f()//1 5 
    

    匿名函数作为fun的返回值被赋值给了f,
    这时候相当于 f=function(){var n = 0 … },
    并且匿名函数内部引用着fun里的变量num,所以变量num无法被销毁,
    而变量n是每次被调用时新创建的,所以每次 f 执行完后它就把属于自己的变量连同自己一起销毁,
    于是乎最后就剩下孤零零的num,于是这里就产生了内存消耗的问题

    3. 定时器与闭包

    //写一个for循环,让它按顺序打印出当前循环次数
    for (var i = 0; i < 5; ++i) {
        setTimeout(function () {
            console.log(i + ' ');
        }, 1000)
    }
    // 按照预期它应该依次输出1 2 3 4 5,而结果它输出了五次5,这是为什么呢?
    // 原来由于js是单线程的,所以在执行for循环的时候定时器setTimeout被安排到任务队列中排队等待执行,
    // 而在等待过程中for循环就已经在执行,等到setTimeout可以执行的时候,for循环已经结束,i的值也已经变成5,
    // 所以打印出来五个5,那么我们为了实现预期结果应该怎么改这段代码呢?(ps:如果把for循环里面的var变成let,也能实现预期结果)
        
    for (var i = 0; i < 5; ++i) {
        (function (i) {
            setTimeout(function () {
                console.log(i + ' ');
            }, 1000)
        })(i)
    }
    // 引入闭包来保存变量i,将setTimeout放入立即执行函数中,将for循环中的循环值i作为参数传递,100毫秒后同时打印出1 2 3 4 5
    // 那如果我们想实现每隔100毫秒分别依次输出数字,又该怎么改呢?
    for (var i = 0; i < 5; ++i) {
        (function (i) {
            setTimeout(function () {
                console.log('100 * i', i);
            }, 100 * i)
        })(i)
    }
    // 在这段代码中,相当于同时启动3个定时器,i*100是为4个定时器分别设置了不同的时间,同时启动,
    // 但是执行时间不同,每个定时器间隔都是100毫秒,实现了每隔100毫秒就执行一次打印的效果。
    
    /**********************************②闭包作为参数传递*****************************************/
    var num = 15;
    var f1 = function (x) {
        if (x > num) {
            console.log('闭包作为参数传递', x);
        }
    }
    
    void function (f2) {
        var num = 100;
        f2(30)
    }(f1)
    
    //在这段代码中,函数 f1 作为参数传入立即执行函数中,在执行到f2(30)的时候,30作为参数传入fn1中,
    // 这时候if(x>num)中的num取的并不是立即执行函数中的num,而是取创建函数的作用域中的num这里函数创建的作用域是全局作用域下,
    // 所以
    

    最后总结一下闭包的好处与坏处
    好处
    ①保护函数内的变量安全 ,实现封装,防止变量流入其他环境发生命名冲突
    ②在内存中维持一个变量,可以做缓存(但使用多了同时也是一项缺点,消耗内存)
    ③匿名自执行函数可以减少内存消耗

    坏处
    ①其中一点上面已经有体现了,就是被引用的私有变量不能被销毁,增大了内存消耗,造成内存泄漏,解决方法是可以在使用完变量后手动为它赋值为null;
    ②其次由于闭包涉及跨域访问,所以会

    https://blog.csdn.net/weixin_43558749/article/details/90905723

    相关文章

      网友评论

          本文标题:js 闭包(面试题)

          本文链接:https://www.haomeiwen.com/subject/xdmsoltx.html