深入理解闭包

139 阅读2分钟

一、JS中函数是一等公民

在JavaScript中,函数可以

  • 作为赋给一个变量
  • 作为参数传递给另一个函数
  • 作为另一个函数的返回值 所以我们说JavaScript的函数是“一等公民”。

二、闭包概念

  • 当一个嵌套的内部函数引用了嵌套的外部函数的变量时就会产生闭包
  • 闭包产生条件:
    1. 执行外部函数
    2. 函数嵌套
    3. 内部函数引用了外部函数的数据(变量/函数)
  • 闭包的作用:
    1. 使用函数内部的变量时,在函数执行完后仍然存活在内存中(延长局部变量的生命周期)
    2. 让函数外部可以操作(读写)到函数内部的数据(变量/函数)

三、闭包图解

function foo(){
    var name = "foo"
    function bar(){
        console.log('bar',name)
    }
    return bar
}
var fn = foo();
fn();

image.png

  • 执行到var fn = foo();时内存表现,此时fn指向的是bar的函数地址fn: 0xb00,foo函数执行完时该函数执行上下文将会弹出全局执行上下文栈,且该AO对象不会被销毁
  • foo函数执行完时该AO对象不会被销毁原因是:该函数下有个bar方法中有个name属性是指向父级作用域(foo函数),如函数中没有任何函数指向该对象时,该函数在执行完后就会被销毁。

image.png

  • 执行到最后一行fn();时内存表现

image.png

  • 当fn()函数执行完时,bar函数的执行上下文和该AO对象会被销毁,但其foo的AO对象还是保存在内存中(该操作被称之为内存泄漏)

image.png

  • 不需要使用该内存指向时(不再需要执行bar函数时),使用fn = null解决闭包产生的内存泄露问题