闭包函数栗子
概念:函数的AO通过scope chain相互连接起来,使得函数体内的变量都可以保存在函数的AO,这样的特性称为“闭包”。
<script>
function outer(){
var scope="outer";
function inner(){
return scope;
}
return inner;
}
var fn=outer();
console.log(fn());
</script>
运行结束由于fn指向了inner ,inner拿着scope chain的拷贝、所以outer的AO没有释放
闭包的危险
闭包会造成原有的AO不释放,产生内存泄漏。
这里的内存泄露,指的事非正规的内存的占用。内存泄漏是源于英文的翻译,内存是源于硬件泄漏描述的不合理,是内存使用的不合理得不到释放。
闭包的引用
<script>
//实现共有变量
//累加器
function add(){
var count=0;
function addAction(){
count++;
console.log(count);
return count;
}
return addAction;
}
var myAdd= add();
myAdd();
myAdd();
myAdd();
</script>
<script>
//缓存存储结构
function add(){
var count=0;
function addAction(){
count++;
console.log(count);
return count;
}
function clearAction(){
count=0;
console.log(count);
}
return [addAction,clearAction];
}
var myAdd= add();
myAdd[0]();
myAdd[0]();
myAdd[0]();
myAdd[1]();
</script>
<script>
//使用方法操作变量、模块化操作,避免了变量的污染
function add(){
var count=0;
var adder={
addAction: function(){
count++;
console.log(count);
return count;
},
clearAction:function (){
count=0;
console.log(count);
return count;
}
};
return adder;
}
var myAdd= add();
myAdd.addAction();
myAdd.addAction();
myAdd.addAction();
myAdd.clearAction();
myAdd.addAction();
</script>
列题
<script>
function outer(){
var result=new Array();
for(var i=0;i<2;i++)
{
result[i]=function(){
return i;
}
}
return result;
}
var fn=outer();
console.log(fn[0]());
console.log(fn[1]());
/**
* outer()声明:脚本的scope chain ->copy [GO] ,生成自己的:[GO,outer-AO]
* result[0]=function(){}:outer的scope chain -> copy [GO,outer-AO] ,没有运行
* result[1]=function(){}:outer的scope chain -> copy [GO,outer-AO] ,没有运行
*/
</script>
注意:函数的表达式和声明是不一样的,表达式是在运行时copy的scope chain。函数声明拿到的scope chain是在预编译。所以当result运行时 i已经等于2了