闭包为什么会造成内存泄漏?

本文详细解释了JavaScript中闭包的概念,包括其如何通过保留对外部函数作用域的引用而工作,以及这种特性如何导致内存泄漏。同时,文章探讨了闭包在函数执行后的内存管理机制,以及如何通过解除对匿名函数的引用来减少闭包造成的内存占用。

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

本文基于《JavaScript高级程序设计》整理。

闭包概念:

闭包是一类函数。哪一类?有权访问 另一个 函数 作用域中变量的函数。

想要理解闭包,必须从理解函数被【调用】的时候会发生什么入手。

每次复习闭包的相关知识,我都习惯把作用域和闭包一起复习。

函数的作用域链

1.创建函数outerFun()时,会创建一个预先包含全局变量对象的作用域链,保存在内部的[[Scope]]属性中。

2.调用函数outerFun()时,为此函数创建一个执行环境。

3.然后复制函数的[[Scope]]属性中的对象构建起执行环境的作用域链

4.此后,创建一个活动对象,推入执行环境作用域链的前端([0]位置)。

此时执行环境的作用域链中包含两个变量对象:全局变量对象(第3步) 、 局部活动对象(第4步)

函数中访问一个变量时,就会从作用域链中搜索具有相应名字的变量。

函数执行完后,局部活动对象被销毁,内存中仅保存全局作用域。

闭包的情况

?内部函数 被 外部函数 包含时,内部函数会将外部函数的局部活动对象添加到自己的作用域链中。

outerFun(outerArgument){
    //被包含的内部函数可以访问外部函数的变量
    return function(){  
        return outerArgument+1
    } 
} 

而由于内部匿名函数的作用域链 在引用 外部包含函数的活动对象 ,即使outFun执行完毕了,它的活动对象还是不会被销毁!

即,outerFun的执行环境作用域链都销毁了,它的活动对象还在内存中留着呢。

并且根据垃圾回收机制,被另一个作用域引用的变量不会被回收。

所以,除非内部的匿名函数解除对活动变量的引用(解除对匿名函数的引用),才可以释放内存。

// 创建函数 还未调用
var creatFun = outerFun(7)
// 调用函数
var result = creatFun(8)
// 解除对匿名函数的引用
creatFun = null

所以,闭包会造成内存泄漏,就是因为它把外部的包含它的函数的活动对象也包含在自己的作用域链中了,会比一般的函数占用更多内存。

如何减少闭包占用的内存问题?见下一篇:闭包如何减少内存占用?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值