自从学习js时,一直卡在闭包中过不去,索性就花了点时间好好研究了一下闭包的原理,拜读了各位技术大牛的研究作品后,才略懂一二,一下是我对闭包的一些浅薄理解,希望能对学习js的各位有点帮助。
闭包,官方的解释是一个拥有许多变量和绑定了这些变量的环境表达式(通常是一个函数)。这样的定义太空泛,理解起来实在是比较困难。我先引入下面一个例子帮助大家进行理解:
function foo (x) {
var temp=3;
function bar (y) {
alert(x+y+(++temp));
}
bar(10);
}
foo(2);
这只是简单的函数调用,还不是一个闭包,但如果写法改成一下的形式:
function foo (x) {
var temp=3;
return function(y) {
alert(x+y+(++temp));
}
}
var f=foo(2);
f(10);
这样的形式中,f就是一个闭包。我总结出一个闭包的简单定义,凡为闭包,都要满足三个条件:1、存在函数嵌套函数;2、外部函数return了内部函数;3、内部函数包含了外部函数的变量。满足这三个条件,就存在闭包。用好闭包,在js中可以起到很多作用,上述例子中,闭包体现出了它的一个作用:允许外部变量引用函数内部的变量。接下来讲它的第二个作用:
function f1 () {
var n=999;
nAdd=function () {//未用var定义,说明为全局变量
n+=1;
}
function f2 () {
alert(n);
}
return f2;
}
var result=f1();
result();//结果为:999
nAdd();
result();//结果为:1000
上述例子的n变了值,第一次为999,第二次为1000,这证明了两次result()中的n是同一个,也就是n一直保存在内存中,没有在f1被调用结束后清除。这不符合常理,为何?原因就是闭包,因为f2被赋予一个全局变量(result),导致f2始终存在于内存中,而f2又依赖于f1,固f1也始终在内存中。这就是闭包的第二个作用:能使某些局部变量始终存在于内存中。
如果这样还是觉得不能理解,ok,我们换成java的思路:
外部函数相当于一个类,它的变量都是私有成员,其他类无法访问,,但如果我们用闭包封装一个函数来调用私有成员,就可以在其他类中对该成员进行操作,相当于将getter&setter方法设置为public,直接通过getter&setter方法对私有成员变量进行操作。例子如下:
var person=function () {
var name="default";
return {
getName:function () {
return name;
},
setName:function (newName){
name=newName;
}
}
}();
alert(person.name);//结果为undefined,因为无法直接访问
alert(person.getName());//结果为default
person.setName("孙悟空");
alert(person.getName());//结果为孙悟空
以上就是我对于闭包的一些理解,感谢期间提供研究资料的各位大神!谢谢!
http://www.cnblogs.com/frankfang/archive/2011/08/03/2125663.html
http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html