闭包经典前端面试题目

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(); //10 alert(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;
原文地址:https://www.cnblogs.com/Zqian/p/7689129.html