给大家整理了下闭包的相关问题,能帮助加深对闭包的理解。
问题一:
function f1(){
var n=999;
nAdd=function(){n+=1}
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result(); // 999
nAdd();
result(); // 1000
解析
第一步,result是f2函数
第二步,执行result就是执行f2函数,又因为闭包使得f2能访问除本身函数之外的变量,能访问到变量n,所以结果是999
第三步,因为nAdd没有加var所以是全局变量。nAdd中能向下访问局部变量n=999,所以执行后n=1000
第四步,执行result,又执行f2,输出n,所以n是1000
拓展
function f1(){
var n=999;
nAdd=function(){n+=1}
function f2(){
alert(n);
}
return f2;
}
var result1=f1();
var result2=f1();
result1(); // 999
result2();//999
nAdd();
result1(); // 是999而不是1000,这是为何呢?
result2();//1000
这是因为产生了两份闭包作用域。nAdd得到的是最新的作用域中的n。
这个不是很清楚,清楚的麻烦留言……
问题二
function fun(n,o) {
console.log(o);
return {
fun:function(m) {
return fun(m,n);
}
};
}
var a = fun(0); a.fun(1); a.fun(2); a.fun(3); //undefined,0,0,0
var b = fun(0).fun(1).fun(2).fun(3); //undefined,0,1,2
var c = fun(0).fun(1); c.fun(2); c.fun(3); //undefined,0,1,1
解析
这个问题是经典的闭包问题
第一步,fun(0)返回的是fun(m,0);因为没有第二个参数,所以输出undefined
第二步,a.fun(1)相当于fun(m,0).fun(1),因为闭包的作用n会保留在作用域中,也就是0还在内存中,所以最后返回的是fun(1,0)因此输出的是0
第三步,a.fun(2)和第二步同理
第四步,a.fun(3)和第二部同理
接着
第一步,fun(0)返回的是fun(m,0);因为没有第二个参数,所以输出undefined
第二步,fun(0).fun(1)相当于是fun(m,0).fun(1),因为闭包的作用n会保留在作用域中,也就是0还在内存中,所以最后返回的是fun(1,0)因此输出的是0
第三步,fun(0).fun(1).fun(2)相当于fun(1,0).fun(2),因为闭包的作用n会保留在作用域中,也就是1还在内存中,所以最后返回的是fun(2,1)因此输出的是1
第四步,fun(0).fun(1).fun(2).fun(3)相当于fun(2,1).fun(3)同第三步,因此输出的是2
接着
想必看到这你就知道了为什么是undefined,0,1,1了。原因同上边的解释。我就不啰嗦了。
参考文献
https://segmentfault.com/q/1010000002880935
http://www.jb51.net/article/75450.htm
http://blog.csdn.net/yueguanghaidao/article/details/9568071 这篇说的也挺好