Javascript闭包及其应用

闭包是什么?关于闭包,最简单的描述就是 ECMAScript 允许使用内部函数--即函数定义和函数表达式位于另一个函数的函数体内。
这句话太晦涩难懂,要深入理解闭包,我觉得要弄懂它的作用是什么才算是真正理解。我们知道,在函数内部定义的变量,其外部是无法访问的。
首先来看一个例子

function a(){
	var i =0;   //注意不能写成 i=0
}
a();
alert(i);

发现函数执行返回了一个错误,说明函数内部的变量不能被访问

如果函数a内部有另外一个函数b,而且a执行之后返回b,b函数中又访问了a函数的变量,会出现什么情况呢
再看第二个例子

function a(){
	var i=0;
	function b(){
		i++;
		alert(i);
	}
	return b;
}	
var res=a();
res();		//弹出1
res();		//弹出2

解析一下这个例子:由于res=a();实际上 res=function b(){i++;alert(i)},如果安装普通的情况,当a函数执行完毕之后,变量i应该是被销毁的,从函数执行的结果来看,弹出的数字出现了累加,可以证明这个变量实际上是没有被销毁,一直保存在内存当中的,只是没有一个“引用”去访问它。可以说,这就是闭包最典型的一个特征了,当一个函数内的变量需要去访问它的父函数的局部变量,并且父函数执行之后,返回这个子函数,那么就形成了一个闭包。

那么闭包究竟有什么意义呢,像上面那个例子,我们完全可以把变量赋值成全局变量啊,不一样可以用吗?

下面来看个例子:(封装)

	var obj={
	name:"Dvida",
	 age:20,
	 sex:"male",
	 say:function(){alert("my name is "+this.name)}
	}
obj.say();

在上面这个例子中,我们定义了一个对象obj,这个对象中有三个属性,他们都能分别访问。
obj.name; //Dvida
obj.say(); //my name is i have no name

原来对象就这样轻易被改写。利用闭包的特性,我们可以避免这个问题, 还是刚才这个对象,我们重新定义一下

var obj =function (){
	var name="Dvida";
	return {
		say:function(){alert("My name is "+name)},
		getname:function(){return name},
		setname:function(newname){name=newname}
	}
}()
obj.name; //undefined
obj.getname();//Dvida
obj.setname("Jack");//对象的名字被改写

匿名函数内部立即执行
匿名函数立即执行也可以看作是一个闭包,如:

(function(){
	var a=document.title;
	var b="这是我的网站";
	document.title=a+b;
})()

这个匿名函数的外部没办法通过任何方式改变其内部的变量,在一些统计类工具中比较常见,如Google统计

发表评论