JavaScript闭包的理解和使用场景、闭包的优缺点,以及解决内存泄露的方法(附带案例)

💂 个人网站: 【紫陌】【笔记分享网】
💅 想寻找共同学习交流、共同成长的伙伴, 请点击【前端学习交流群】

1. 对闭包的理解


        闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,创建的函数可以访问到当前函数的局部变量。

简单的例子:

    function fn() {
            var num = 100;    //fn函数作用域内部的变量
            function fun() {
                console.log(num);    //fun函数可以访问fn函数变量
            }
            fun();
        }
        fn();

//可以简写成
            function fn() {
            var num = 100;    //fn函数作用域内部的变量
            return function() {    //直接return匿名函数
                console.log(num);    //fun函数可以访问fn函数变量
            }
        }
        let f = fn()
        f()
        //类似于
        // let f = function() {
        //         console.log(num);
        //     }

2.闭包的原理

作用域链,当前作用域可以访问上级作用域中的变量,闭包也可以说一种现象。

3.闭包的用途

  1. 访问函数内部的变量
  2. 防止函数内部的变量执行完城后,被销毁,使其一直保存在内存中。

4.闭包的优点缺点

  • 优点:可以延伸变量的 作用范围
  • 缺点:由于垃圾回收器不会将闭包中变量销毁,于是就造成了内存泄露,内存泄露积累多了就容易导致内存溢出。所以使用完闭包后,可以通过手动对闭包 f = null(看下面代码) ,让垃圾回收器回收

内存泄漏的解决方法:

    function fn() {
            var num = 100;
            return  function (){
                console.log(num++);    //每次调用加一
            }
        }
       let f = fn()
       f()    //100
       f()    //101
       f()    //102
       f = null       // 手动释放fn()的引用 
       var f1 = fn()    // fn()的引用f()被释放了,现在fn()的作用域也被释放了。fn()再次归零了。
       f1()    //100

5. 闭包的应用场景

  • 采用函数引用方式的setTimeout调用。
  • 将函数关联到对象的实例方法。
  • 给对象设置私有变量并且利用特权方法去访问私有属性
  • 防抖节流函数
  • Vue中数据响应式Observer中使用闭包等。

案例:

需求:点击li输出当前li的索引号

<body>
    <ul class="nav">
        <li>吃饭</li>
        <li>睡觉</li>
        <li>打游戏</li>
        <li>打豆豆</li>
    </ul>
    <script>
         // 1. 我们可以利用动态添加属性的方式
        var lis = document.querySelector('.nav').querySelectorAll('li');
        // 2. 利用闭包的方式得到当前小li 的索引号
        for (var i = 0; i < lis.length; i++) {
            // 利用for循环创建了4个立即执行函数
            // 立即执行函数也成为小闭包因为立即执行函数里面的任何一个函数都可以使用它的i这变量
            (function(i) {
                // console.log(i);
                lis[i].onclick = function() {
                    console.log(i);

                }
            })(i);
        }
    </script>
</body>

需求:3秒钟之后,打印所有li元素的内容

<body>
    <ul class="nav">
        <li>吃饭</li>
        <li>睡觉</li>
        <li>打游戏</li>
        <li>打豆豆</li>
    </ul>
    <script>
        // 闭包应用-3秒钟之后,打印所有li元素的内容
        var lis = document.querySelector('.nav').querySelectorAll('li');
        for (var i = 0; i < lis.length; i++) {
            (function(i) {
                setTimeout(function() {
                    console.log(lis[i].innerHTML);
                }, 3000)
            })(i);
        }
    </script>
</body>

看完点赞!!!

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值