要想明白闭包的概念,我认为首先应该了解javascript中的函数变量的作用域和作用域链,只有知道了上述两个概念,才能对闭包有清晰的认识。
1.变量作用域:
var n =3;
function a(){
alert(n);
}这里程序不会报错,会正常执行,因为n是全局变量,函数内部是可以访问到全局变量的。
function a(){
var n = 3;
}
alert(n);然而在这里,程序会报错,因为在函数外部是访问不到函数内部的变量的。
但有一点需要注意,如果这里的代码如下
function a(){
n = 3;
}
alert(n);这里的n在声明的时候没有用到var,n是一个全局变量,所以可以访问到n。2.作用域链
var n = 2;
function a(){
var n = 3;
function b(){
var m = 4;
alert(n);
}
b();//3
alert(n);
alert(m);
}
a();//2,undefined这里首先声明了一个全局变量p=2,紧接着是一个函数a,函数内部声明了局部变量n,和函数a内部一个函数b,函数b内部声明变量m。执行结果如注释,结果说明了最内部的函数是可以访问到函数外部的变量的,但是在a函数是访问不到b函数内部的局部变量的。而且,此时函数b访问到的变量n是函数a内部的变量n,最外层的全局变量n。
这里的程序执行结果,就是作用域链的效果。
简单来说,js中的内部函数是可以访问到父函数中定义的变量的,父函数中没有,就去全局变量中寻找。
然而内部函数中定义的变量,外部是访问不到的。那么,如果我们想在函数外部访问函数内部的变量要怎么办呢?
闭包就是起了这样的作用。这里先来看一段代码:
function a(){
var n = 100;
return function(){
alert(n);
}
};
var result = a();
result();在这里,我们返回了一个内部匿名函数,匿名函数内部调用了父函数的局部变量,返回的匿名函数在全局环境中得到了执行,所以就实现了在函数外部访问其内部变量,这里的内部函数就是起到了闭包的作用。
下面看几个例子:
function a(){
var result = new Array();
for(var i=0; i<10; i++){
result[i] = function () {
return i;
}
}
return result;
};这里返回的函数中的i值都是多少呢?答案是全部是10,因为当返回的内部函数在全局环境中去访问a函数内部的i的时候,i的状态保持在了return的那一时刻,所以i=10
function outerFun()
{
var a=0;
function innerFun()
{
a++;
alert(a);
}
return innerFun;
}
var obj=outerFun();
obj();
obj();
var obj2=outerFun();
obj2();
obj2(); </span>
结果分别为1,2,1,2 由于obj 和obj2是两个不同的实例,所以a的值都是重新从a=0开始访问的。这里返回了innerFun,是的outerFun的实例可以再调用一次。
关于闭包的实例还有很多,之后会继续补充。
8462

被折叠的 条评论
为什么被折叠?



