js闭包的理解与内存泄漏的解释

本文深入探讨了JavaScript中的闭包概念,从广义和狭义角度解释了闭包的定义,并通过代码实例展示了闭包如何形成。同时,文章讨论了闭包可能导致的内存泄漏问题,解释了内存泄漏的原因及如何避免,强调了释放不再使用的函数引用以防止内存占用的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、闭包的定义

我们先看一段代码:

function foo() {
  var name = "foo"
  function bar() {
    console.log("bar", name)
  }

  return bar
}

var fn = foo()
fn()

我对闭包的理解:

一个普通的函数(bar),如果它可以访问外层作用域的自由变量(name),那么这个函数就是一个闭包

广义的角度:

JavaScript中的函数都是闭包

狭义的角度:

JavaScript中一个函数,如果访问了外层的变量(上层作用域的变量),那么它是一个闭包;否则,它不是一个闭包

比如test1访问了外层的自由变量(name),那么test1函数是一个闭包;但是,test2没有访问外层的自由变量,所以test2不是一个闭包。

var name = "kk"
// 这个函数访问了外层作用域的变量
function test1() {
  console.log(name)
}

// 这个函数没有访问外层作用域的自由变量
function test2() {
  console.log('test2函数没有访问外层作用域的变量');
}

二、闭包的内存泄漏

先看下面的闭包:

function foo() {
  var name = 'zyk'
  var age = 20

  function bar() {
    console.log(name);
    console.log(age);
  }

  return bar;
}

var fn = foo()

fn()

下面是上面代码的执行过程:

解析:(根据GC算法-标记清除)原本当每个函数执行上下文栈执行完后,它对应的AO对象都会被销毁,但是,这里的GO对象的属性fn指向bar函数的内存地址,然后bar函数的内存地址又指向foo函数的AO对象,只要GO对象一直指向,那么AO对象永远都不会都不会被销毁。 这就是闭包的内存泄漏

销毁内存泄漏:

如果后续我们不再使用fn函数了,那么该函数对象应该要被销毁掉,并且其引用着的父作用 域AO也应该被销毁掉; 但现在fn引用了bar函数对象,所以不能被销毁。如果将fn = null,则可以解决内存泄漏,当设为null,则fn只会指向一个空的地址,bar的函数对象则没有给引用,则会给销毁,AO也会被销毁掉。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值