JS 闭包

72 阅读2分钟

闭包什么

  • 闭包是一个函数和对其周围状态(作用域链)的引用捆绑在一起的组合
  • 闭包可以让你在一个内层函数中访问到其外层函数作用域
  • 在JS中,每当创建一个函数闭包就会在函数创建的同时被创建出来

个人理解:一个普通的函数function,如果它可以访问外层作用域的自由变量,那么这个函数和周围环境就是一个闭包

image.png 函数fun的作用域里可以访问作用域1里的变量,所以作用域2和函数fun就是一个闭包

闭包使用过程内存图

function createAdder(count){
    function adder(num){
        return count + num
    }
    
    return adder
}

var adder5 = createAdder(5);

adder5(100);

初始: image.png

执行第九行代码: 第一步: image.png

第二步: image.png

结束后,栈内存中add5的值为0x300

执行第11行代码:

第一步: image.png 第二步:

使用add5函数对象的作用域链查找count值,并计算

image.png

计算结束后由于adder5活动对象由于没有被引用,所以内存空间被释放 但是由于adder5任然指向0x300,故createAdder活动对象和adder函数对象依然互相引用中,所以内存空间无法释放,继而造成了内存泄漏

image.png

闭包的漏洞——内存泄漏

内存泄漏:对于我们来说永远不会再使用的对象,但对于垃圾回收机制来说,它不知道要进行释放的对应内存任然会保留着。此现象被称为内存泄漏。

  • 手动对内存进行释放:adder5 = null

垃圾回收机制根据标记清除算法进行清除时,createAdder活动对象和adder函数对象没有被引用,所以内存空间会被清除。