您的位置:首页 > Web前端 > JavaScript

js闭包详解

2015-09-06 16:08 459 查看
以前只听说过闭包(closure),并没有深入研究过,今天来仔细看一看闭包究竟是个什么东西。

1.认识闭包

闭包:是一个有权访问另一个函数作用域中的变量的函数。通常创建的方法是在一个函数内创建另一个函数,是该函数可以访问其局部变量。

优点:可以使函数的局部变量被保存在内存中,不被js垃圾回收器销毁。避免全局变量被污染。正常情况下,局部变量在函数执行完成后会被销毁,而闭包可以使该变量不被销毁。

缺点:闭包会常住内存,对内存消耗大,容易造成内存溢出,在IE上更易崩溃。可在使用完后使对象等于null来清空对象。



2.了解作用链

作用链:js中所有的变量都是对象的一个属性,而该对象可能也是另一个对象的属性,但所有对象都是window对象的属性,那么他们之间的关系就形成了一个链式,即是作用链。

作用域:是js变量的生命活动范围,超出该范围将会被GC销毁。

注意:在js中没有用var声明的变量是全局变量,且是window对象的属性,有var声明的变量才是局部变量,归函数所有。

3.闭包的特性

a.闭包是一个嵌套在函数中的函数。

b.函数内部可以引用外部函数的参数和变量。

c.闭包的参数和变量不会被垃圾回收机制回收。

(垃圾回收机制:回收不被引用的对象;回收2个互相引用而不被第3者引用的对象)

4.实例分析

<script type="text/javascript">
	var a = [];
	function testa(){
		var i= 0;
		for (;i<3;i=i+1){
			a[i]=function(){
				alert(i);
			};
		}
	}
	testa();
	a[0]();//3
	a[1]();//3
	a[2]();//3
</script>


上诉代码对数组a使用了闭包结构,i变量确实被存储了,但是却全部变成了3,这是因为闭包中所存储的变量并不是变量的值,而是闭包的一个引用,当testa方法执行完成后,i变量已经成为了3,之后在引用i时,只会是3.那么如何存储所有变量呢,我们可以让内部函数在循环创建的时候立即执行,并且捕捉当前的索引值,然后记录在自己的一个本地变量里.然后利用返回函数的方法,重写内部函数,让下一次调用的时候,返回本地变量的值,例如:

<script type="text/javascript">
	var a = [];
	function testa(){
		var i= 0;
		for (;i<3;i=i+1){
			a[i]=(function(i){//立即执行当前方法
				return function(){//重写返回方法
					alert(i);
				};
			})(i);//记录i的当前值
		}
	}
	testa();
	a[0]();//0
	a[1]();//1
	a[2]();//2
</script>
这里的return是一个闭包函数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: