理解闭包(力扣大佬写的,受教了)

什么是闭包?

在JavaScript中,闭包(closure)是指函数与其词法环境的组合。它允许函数在其定义的词法作用域之外访问变量,并保持对这些变量的引用,即使在函数外部被调用时仍然有效。

闭包由两个主要部分组成:

函数:闭包是一个函数,它定义了一些变量和逻辑。
词法环境:词法环境是在函数定义时创建的作用域,它包含了函数中定义的变量和它们的值。
从广义上来说,任何JavaScript函数都是闭包,比如在浏览器中,任何一个函数都有一个global对象,那就是window,而在node环境中,每个函数也有一个global对象。

从狭义上来说,JavaScript中一个函数,如果访问了外层作用域的变量,那么它是一个闭包。

通俗易懂地讲,一个普通的函数function,如果它可以访问外层作用于的自由变量,那么这个函数就是一个闭包。

闭包的形成过程

现在有如下代码。

function makeAdder(base) {
	return function (num) {
        return base + num;
    }
}

const add10 = makeAdder(10)
console.log(add10(5)); // 15

当makeAdder函数执行完毕,正常情况下我们的Activation Object(AO)对象会被释放;但是在返回的函数中,有作用域引用了这个AO对象的base,所以它不会被释放。

Activation Object是什么?
当一个函数执行的时候,会创建一个Activation Object。该对象会存储该函数体内的变量以及arguments等信息。

闭包的内存泄露

在上面的案例中,如果后续我们不再使用add10函数了,那么该函数对象应该要被销毁掉,并且其引用着的父作用域AO也应该被销毁掉;但是目前因为在全局作用域下add10变量对makeAdder执行后的函数对象(AO)有引用,所以最终会造成这些内存都是无法被释放的;
所以我们经常说的闭包会造成内存泄露,其实就是刚才的引用链中的所有对象都是无法释放的;

解决内存泄露

add10 = null
//根据GC机制,将add10引用赋值为null,就不会有引用指向makeAdder创建出来的函数对象,从而也会将其销毁

闭包中未使用外层的属性是否被销毁?

function makeAdder(base) {
  const msg = "hello"
	return function (num) {
  	return base + num;
  }
}
这段代码中,base和msg都属于父级作用域中的AO,base不会被销毁,但msg会被销毁

作者:CoderYoo
链接:https://leetcode.cn/problems/create-hello-world-function/solutions/2272042/ni-bu-zhi-dao-de-bi-bao-by-coderyoo-w3rl/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值