闭包

闭包是指有权访问另一个函数作用域中的变量的函数,简单点就是一个函数内部创建另个函数。

什么是闭包

简单点讲就是当前的函能够访问另外一个函数作用域中的变量,但是我们要这么分析他在js中到底是怎么运行的,当函数创建的时候,会创建一个预先包含全局变量对象的作用域链,当我们访问执行完函数的时候就会生成一个执行环境,这个执行环境的作用域链复用了刚才的那个作用域链并添加属于自身的活动变量,当函数执行结束的时候这个执行环境就会被回收 ,所以就不存在闭包这个东西,但是当函数应用了其他函数的变量的时候,那么当我们执行完函数后因为他应用了外部作用域的变量,牵扯到了外部函数的执行环境,但是理论来说外部函数执行完后执行环境就会被回收,那么如果按照这个理论的话那么这里的执行就会出现问题,因为内部函数的执行的时候就会找不到外部的变量。为了避免这个问题出现,javascript就将外部作用域的变量保存了下来,也就是外部作用域的信息被保存了下来,也因此有了闭包有可能会导致内存泄漏的这个概念

变量对象

后台的每个执行环境都有一个表示变量的对象–变量对象。

作用域链

在创建函数时,会创建一个预先包含全局变量对象的作用域链,这个作用域链被保存在内部的[[scope]]属性中,当调用函数的时候,会为函数创建一个执行环境,然后通过复制函数的[[scope]]属性中的对象构建起执行环境的作用域链。

闭包

由于闭包会携带包含它的函数的作用域,因此会比其他函数占用更多的内存。
闭包只能取得包含函数中任何变量的最后一个值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//错误
function a(){
var arr=new Array();
for(var i=0;i<10;i++){
arr[i]=function(){
return i;
}
}
return arr;
}
输出的数组的值都是10
//正确
function a(){
var arr=new Array();
for(var i=0;i<10;i++){
arr[i]=function(){
    return function(){
return i;
}  
   }
}
return arr;
}

内存泄漏

由于IE9之前的版本对JScript对象和com对象使用不同的垃圾收集例程,因此闭包在IE的这些版本中会导致一些特殊的问题,那么,如果闭包的作用域链中保存着一个HTML元素,那么久意味着该元素无法销毁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function a(){
var ele=document.getElementById("box");
ele.onclick=function(){
alert(ele.id);
}
}
//由于匿名函数保存了一个对a函数的活动对象ele的引用,因此就会导致无法减少ele的引用数,只要匿名函数存在,ele的引用书至少也是1,因此他占用的内存永远无法被回收

//优化
function a(){
var ele=document.getElementById("box");
 var id=ele.id;
 ele.onclick=function(){
alert(id);
}
ele=null;
}
这样就不会出现上面那个问题了

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器