之前我对闭包的理解是有权访问另一个函数中的变量的函数但是我发现这样只是解释了闭包的现象,并没有说清楚原理,于是我再次研究了闭包有了一些新的见解。
想要说清楚闭包的原理得先了解 AO(活动对象) VO(变量对象)对于他们的解释请自行百度不做过多解释。那直接开始吧!
当执行到某函数时,在创建上下文环境的时候,会创建作用域,this,以及活动对象,活动对象就是js在分析当前环境有哪些变量,函数(变量提升)时创建的,在函数执行完之后会跳出到当前上下文并销毁,但是活动对象会保留,闭包引用的外部变量,其实是活动对象里面的,这样垃圾回收机制(标记清除)就不会回收,所以才能访问到闭包里的参数。
function createCounter(initial) {
var counter = initial;
function increment(value) {
counter += value;
}
function get() {
return counter;
}
return {
increment: increment,
get: get
};
}
var myCounter = createCounter(100);
console.log(myCounter.get()); // 返回 100
myCounter.increment(5);
console.log(myCounter.get()); // 返回 105
当调用 createCounter(100) 时,内嵌函数increment和get都有指向createCounter(100) scope的引用。假设createCounter(100)没有任何返回值,那么createCounter(100) scope不再被引用,于是就可以被垃圾回收,关系如下图:
但是createCounter(100)实际上是有返回值的,并且返回值被存储在了myCounter中,所以对象之间的引用关系如下图: