function fun(n,p){
console.log(p); 【1】
return{
fun:function(m){
return fun(m,n); 【2】
}
};
}
var a = fun(0);
a.fun(1);
a.fun(2);
a.fun(3);
var b = fun(0).fun(1).fun(2).fun(3);
var c = fun(0).fun(1);
c.fun(2);
c.fun(3);
涉及知识点:
为更好地理解闭包,我们应该知道一些有关闭包的其他问题。
一、私有变量作用域
1.变量分类:私有变量和公有变量,私有变量的作用域为函数体内,(即从函数体开始声明到函数体结束),在函数体外不能访问(如下例1.1)。若声明变量时未使用var,则变量为全局变量。
//例1.1
function a(){ var i = 10;
alert(i);
}
a(); //10alert(i); //error
二、闭包作用
2.闭包的引入:为了使私有变量可以在其他函数内或函数体外访问,闭包的出现满足了需求。闭包就是在一个函数体内创建另一个函数,使得可以访问另一个函数作用域中的变量函数。(例1.2)
//例1.2
function a(){ var i = 10;
function b(){
alert(i); //10;
}
b();
}
a();
三、变量的引用方式
3."链式作用域"结构,子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的.
本例中,b()函数体中无i变量的定义,故向上查找外部函数中的变量,找到i变量后,故输出它的值。
四、例题解析
var a = fun(0); //将a初始化为函数对象,传入参数,使n的值为0,由于传入参数个数不足,其余参数未定义undefined,执行【1】语句,故输入undefined。
a.fun(1); //此时a为上条语句返回的函数对象fun(m,0);调用fun属性返回fun(1,0);此时 p=0;输出0;
a.fun(2); //同上返回fun(2,0),输出0;
a.fun(3); //同上返回fun(3,0),输出0;
var b = fun(0).fun(1).fun(2).fun(3);
//等同于
var b = fun(0); //返回fun(m,0);p 的值undefined;
var b1 = b.fun(1); //先前b已经返回fun(m,0),执行【1】语句,输出0;返回fun(1,0)
var b2 = b1.fun(2); //b1已经返回fun(1,0),执行【2】语句,返回fun(2,1),输出1;
var b3 = b2.fun(3); //b2已经返回fun(2,1),执行【2】语句,返回fun(3,2),输出2;
var c = fun(0).fun(1); //与b1输出相同,输出0;
c.fun(2); //c返回函数对象为fun(1,0),执行【2】,返回fun(2,1),输出1;
c.fun(3); //c返回函数对象fun(1,0),执行【2】,返回fun(3,1),输出1;