闭包经典前端面试题目

时间:2021-12-31 22:40:51
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;