function fn1(){
var i = 0;
function fn2(){
i++;
console.log(i)
}
return fn2;
}
var fn3 = fn1();
fn3();
f2是一个闭包,fn1拥有一个局部变量i,fn1调用结束后,其变量i因为被fn2引用,所以并没有被垃圾回收。
从作用域链的角度理解闭包
实际上,当我们创建一个函数时,[[Scope]]也被创建,[[Scope]]是函数的一个属性(property),它包含了parent的context的VO/AO。而当进入函数上下文时则VO/AO被创建,并进行一些操作,当执行上下文代码时,变量的值被修改。
Scope = VO + [[Scope]];
理解了这个概念后,再看上面的例子:由于fn2的context的属性AO中并没有找到变量i,所以将会往其原型链上查找,同样也查找不到,此时便会向上一级的context的VO/AO属性上查找,最后在fn1的AO上找到变量i。并且由于[[Scope]]是在函数创建时就存在的,所以即使fn1执行完,fn2仍然可以找到变量i。
网友评论