JS闭包
首先,我们先解释一下什么是闭包,闭包就是可以访问其他函数内部变量的函数(其实我的理解是这个其他函数指的是这个函数的父级函数)。
然后什么情况下才会形成闭包呢?当函数内部嵌套函数,并且当内部的函数保存到外部时,便会形成闭包。
谈闭包,就不得不先了解作用域链以及函数变量提升和执行期上下文那些事儿,如果不了解的话,可以去看看我这篇博客点我。
现在,我们还是举个简单的闭包的小栗子吧
function demo1 () {
var count = 0 ;
function demo2 () {
return ++count;
}
return demo2;
}
var temp = demo1() ;
console.log(temp()); //输出1
console.log(temp()); //输出2
首先我们看demo1的AO对象:
AO{
count:undefined,
demo2: fn(){return ++count;}
}
OK,在demo1还没有被执行前,它的AO对象就是这样了。
再往下看,将函数demo1赋值给变量temp,,注意,在函数demo1的最后把内部函数demo2返回出来了,所以,此时temp的值就是demo2的值了。
执行console.log的时候,temp函数被执行,这时,我们分析一下demo2的AO对象:
AO{
}
……有点尴尬,它的AO里面是空的,但是这不要紧,因为它继承了demo1的AO,如图所示(其中demo1指向的demo1的AO和demo2指向的AO是同一个东西,GO也是一样的,在执行函数的时候,函数会按照图上的顺序自上而下的寻找需要的变量和函数):
上一篇博客我说过,当一个函数执行完,它指向其对应AO的指针会消失,但是这里,count是定义在demo1中的变量,所以在demo2中每次改变count,调用的都是最近修改过的最新的count,于是,这就产生了闭包。
JS闭包的好处和坏处
缺点:当产生闭包时,函数的变量和数据会一直存放在内部函数中,无法释放,从而造成内存泄漏。
优点:可以读取函数内部变量,且变量不会被主动清除,起到缓存的作用。