前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JavaScript闭包

JavaScript闭包

作者头像
大熊G
发布2022-11-14 16:47:19
3400
发布2022-11-14 16:47:19
举报

theme: channing-cyan

这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战

闭包是什么

做前端的可太需要了解闭包了,几乎每个面试都会问到闭包,闭包的重要性不言而喻。什么是闭包:闭包一般是指那些引用了另一个函数作用域中变量的函数,通常是在嵌套函数中实现的。也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。

代码语言:javascript
复制
    function f1() {
        var a = 666;

        function f2() {
            console.log(a);
        }
        return f2; // f1返回了f2的引用
    }
    var jackson = f1(); // jackson就是f2函数了
    jackson(); // 执行jackson,全局作用域下没有a的定义,
    //但是函数闭包,能够把定义函数的时候的作用域一起记住,输出666

上面的例子,首先有执行上下文f1,在f1中定义了函数f2,而通过对外返回f2的方式让f2得以执行。当f2执行时,访问了f1内部的变量a。这个时候闭包就产生了。

闭包很有用,因为它允许将函数与其所操作的某些数据(环境)关联起来。这显然类似于面向对象编程。在面向对象编程中,对象允许我们将某些数据(对象的属性)与一个或者多个方法相关联。因此,通常你使用只有一个方法的对象的地方,都可以使用闭包。

this对象

闭包中使用this会让代码变得复杂,之前的文章说过this指向问题,每个函数在被调用的时候都会自动创建俩个特殊变量:this和arguments。内部函数不可以直接访问外部函数的这俩个变量,但是可以把this保存到闭包就可以行得通。我们先看一下直接访问。

代码语言:javascript
复制
    window.identity = 'Jackson';
    let obj = {
        identity: 'bear',
        getIdentityFunc() {
            return function () {
                return this.identity;
            };
        }
    };
    console.log(obj.getIdentityFunc()()); // 'Jackson'

看一下把this保存到变量that。

代码语言:javascript
复制
    window.identity = 'Jackson';
    let obj = {
        identity: 'bear',
        getIdentityFunc() {
            let that = this;
            return function () {
                return that.identity;
            };
        }
    };
    console.log(obj.getIdentityFunc()()); // 'bear'

在定义匿名函数之前,先把this保存一下,在定义闭包时,可以让它访问that,这是因为包含函数中名称没有任何冲突的一个变量。即使在外部函数返回后,that仍然指向obj。

因为闭包会保留他们包含的函数作用域,所以它比其他函数更占用内存,过度使用闭包而不释放的话就会导致过度占用。解决方法是,在退出函数之前,将不使用的局部变量全部删除,我们在之前讲过垃圾回收,点击查看(JavaScript的垃圾回收 (juejin.cn))

内存泄漏

在旧版本浏览器中,尤其是ie,如果把html元素保存在闭包的作用域中,就相当于该元素不能被销毁。

代码语言:javascript
复制
    function clickaaa() {
        let element = document.getElementById('aaa');
        element.onclick = () => console.log(element.id);
    }

这里写了一个点击aaa元素,让它输出aaa的id,只要这个函数存在,element的计数就至少等于1,也就是永远不会被回收。想让它回收的话我们在后面把它释放掉就可以了,大家一定要养成良好习惯。

代码语言:javascript
复制
    function clickaaa() {
        let element = document.getElementById('aaa');
        element.onclick = () => console.log(element.id);
        element = null;//释放
    }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-08-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • theme: channing-cyan
    • 闭包是什么
      • this对象
        • 内存泄漏
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档