闭包
是指在一个函数中声明一个函数,在外部函数结束的时候返回内部函数的引用,那么在执行外部函数的时候就会
产生一个内部函数的引用,因为外部函数执行完成,理论上外部函数的ao的引用是应该被删除或者说释放的。
但因为有了内部函数的引用,这个内部函数在声明的时候就已经指向了外部函数的ao以及go,所以,即使外部函数
ao的引用已经释放,由于内部函数被保存在了外部,导致外部函数申明与执行所产生的ao被保留下来。
<body> <script type="text/javascript"> function a(){ function b(){ var bbb = 234; consloet.log(aaa); };
var a = 123 return b; } var golb = 100; var demo = a(); demo(); </script> </body>
此例的输出结果是:123
按原来的理解,b函数中是没有a这个变量的,正常如果没有外部的a函数,就会报错 a is not define
但是这里,由于在a执行完的时候,把b的引用保存在了函数a之外,而b这个函数在声明的时候,它的scope chain仍然和a执行是同一个,
即:0:aAO;1:GO,就是把a中的执行上下文保存在了b函数中。在执行函数b的时候回生成一个bAO放在scope chain的0位置,执行完的
时候删除这个bAO,而在1、2位置的0:aAO;1:GO被永久的保留了下来。
aAO中是由a = 123这个变量的,故而最终的结果是打印出a的值!~
这 就是闭包!
**注意点**------当内部函数被保存到外部时,将会生成闭包。闭包会导致原有scope chain(作用域链)不释放,造成内存泄漏
内存泄漏:由于内存一直占用,导致可用内存空间减小,感觉就像内存泄漏了一样,就叫内存泄漏了~~!会导致加载非常慢!!
scope chain 中的没生成一个新的ao,必然继承外部函数产生的ao与go,这里的继承是指指向了原来那个AO、GO,而不是生成一个一模一样的
ex:
<body>
<script type="text/javascript">
function text(){
var num = 100;
function b(){
num ++;
console.log(num);
}
function b(){
num --;
console.log(num);
}
return [a,b];
}
var myArr = text();
myArr[0]();
myArr[1]();
</script>
</body>
输出的结果是:101 100
而不是101 99,注意其中的区别!
所以再修改来自外部函数的ao时,是修改的同一个AO
ex:
<body>
<script type="text/javascript">
function a(){
var num = 100;
function b(){
num ++;
console.log(num);
}
return b;
}
var demo = a();
demo();
demo();
</script>
</body>
此例的结果是:101
102
有累加的效果
闭包的作用:1实现共有变量----->函数累加器
2可以做缓存(存储结构)----->eater
3可以实现封装,属性私有化------>Person();
4模块化开发,防止污染全局变量
ex: 实现共有变量----->函数累加器
<body>
<script type="text/javascript">
function add(){
var count = 0;
function demo(){
count ++;
consloet.log(count);
};
return demo;
}
var counter = add();
counter();
counter();
counter();
counter();
counter();
counter();
counter();
counter();
</script>
</body>
输出结果: 1 2 3 4 5 6 7
ex:可以做缓存(存储结构)----->eater 3
<body>
<script type="text/javascript">
function eater(){
var food = "";
var obj = {
eat : function(){
console.log("i am eating!" + food);
food = "";
},
push : function(myfood){
food = myfood;
}
}
return obj;
}
var demo = a();
erter1.push(‘banana‘);
eater1.eat();
</script>
</body>
输出结果; i am eating banana
其中实际有两个过程,一个把banana放入myfood,第二个过程才是打印 i am eating banana
原文:https://www.cnblogs.com/hmd180324/p/9201672.html