闭包的定义
当内部函数被保存到了外面的时候,就会形成闭包,闭包会导致原有的作用域链不释放,造成内存的泄露。
https://blog.csdn.net/qq_28835447/article/details/91616572
作用
1.实现共有变量
2.做缓存
3.实现封装,让属性私有化
4.模块化开发,防止污染全局变量
闭包理解相关:理解预编译,作用域,作用域链
闭包是面试和工作必备技能
例子1
function a(){
var num = 100;
function b(){
num ++;
console.log(num);
}
return b;
}
var fun = a(); //产生fun.AO, fun.AO==a.AO
fun() //101 //fun被调用时 a执行产生b.AO ,b.AO里找不到num则向延function b[[scope]]作用域链向下找
fun() //102 // 函数执行前的一瞬间会生成自己的AO,这是函数执行了2次,生成了两个AO,这两个AO是没有任何关联的,
//而a函数并未重新调用,两次调用都是在同一个a.AO里找num,
//也可以理解为作用域里面的变量,在函数执行完之后依旧保存没有被垃圾回收处理掉。
var fun1 = a(); //此时a函数又重新生成a.AO
fun1() //101
例子2
声明几次就产生几次作用域链
function fun(){
var num = 100;
function a(){
num ++;
console.log(num);
}
function b(){
num --;
console.log(num);
}
return [a,b];
}
var fn_a = fun()[0]; // 生成a.AO a函数作用域里 fun也第一次生成AO
var fn_b = fun()[1]; // 生成b.AO b函数作用域里 fun的第二次生成AO
//他们的AO里没有num,所以回去父级fun.AO里找,重点在于每声明一次就会产生新的作用域链,
// a[[SCOPE]]里的fun.AO与b.[[SCOPE]]里的AO 不是同一个
fn_a();//101
fn_a();//102
fn_b();//99
fn_b();//98
例子3
function fun(){
var play = "";
var obj = {
push : function(abc){
play = abc;
},
player :function(){
console.log('今天' + play);
play = "";
}
}
return obj;
}
var fn = fun(); //fun被定义,产生fun.AO
fn.push("跑步"); //只定义声明了一次,只产生一个fun.AO 所以方法push和方法player在fun.AO里找到修改的play为同一个
fn.player();