闭包
当内部函数被保存到外部时,将会生成闭包。闭包会导致原有作用域链不释放,造成内存泄露。
例子1:
function a() {
function b() {
var bbb = 123;
document.write(aaa);
}
var aaa = 123;
return b;
}
var glob = 100;
var demo = a();// demo 保存的就是b函数
demo();// demo 执行,相当于b函数执行
这个例子中a函数返回了b函数的整体,b函数被返回到了外部。因此形成了闭包。
当b函数被保存出来之后:b被定义时,a执行时的作用域链被保存到了b的作用域链中.
b定义时:
b: scope chain [0] --> AO(从a函数保存下来的)
scope chain [1] --> GO
b执行时:
b: scope chain [0] --> AO(b自身产生的)
scope chain [1] --> AO(从a函数保存下来的)
scope chain [2] --> GO
例子2:
function a(){
var num = 100;
function b(){
num++;
console.log(num);
}
return b;
}
var demo = a();
demo();
demo();
demo保存的b函数,然后将demo执行两次 结果 num = 102
很多的人会认为结果应该是101,其实不是。、
分析:
当b被定义时,b保存了a的作用域链
b: scope chain [0] --> AO(从a函数保存下来的)
scope chain [1] --> GO
当b执行时,
b: scope chain [0] --> AO(b自身产生的)
scope chain [1] --> AO(从a函数保存下来的)
scope chain [2] --> GO
b的AO(执行期上下文)没有变量,而函数体里面执行num++,那么将从作用域向下查找变量num,num属于来自a的AO,当demo执行一次时,num++,AO里面的num = 101;当demo执行第二次时,num++ ,num = 102。
注意:因为b保存了a的作用域链,所以当a执行完毕后,虽然自身的执行期上下文被销毁,但是,a的作用域链已经被保存出去了,所以原作用域链不能被释放