闭包原理理解

105 阅读1分钟

先看一段代码:

var global
function a() {
    function b() {
        var bb = 123
        aa = 0
    }
    var aa = 123
    b()
}
a()

想一下,代码从上往下执行预编译时,在a定义的时候,作用域链是怎样的?

此时 a在全局对象中,并且因为没有执行,内部没有东西。

a开始执行:

a的作用域链应该如下:

a()执行时,解析进入a函数,此时:

作用域链首位变成了a局部变量。

b函数定义时:

进入b后

b函数开始执行时:

b执行完成后,作用域链被销毁,意思就是将上图中的所有线都剪断,待a函数下一次执行,会将上面的线重新连起来,重复上述过程:

理解了上面,闭包就很简单了。

再看下一段代码:

var global

function a() {
    var aa = 123

    function b() {
        var bb = 234
        console.log(aa)
    }
    return b
}
var res = a()
res()

仔细分析,作用域链和前文类似:

很显然a执行产生的作用域链和b定义产生的作用域链它们是一样的,a执行完毕后,它与scope chain连接的线被剪断,但是它执行后返回的b被保存到了res中! 所以b的线并没有被剪断,b仍然可以根据作用域链访问到aa这个变量,当然也能输出 “123”.这就产生了闭包。