理解闭包——闭包中包含递归

有如下代码:

function fun(n,o){
   console.log(o);
   return {
      fun:function(m){
        return fun(m,n);
      }
   };
}

这段代码中既有闭包,也有递归。

先看看这段代码的作用。外层fun(n,o){}函数的执行顺序是:

1、先输出函数的第二个参数o;

2、返回一个对象,该对象包含一个可用.操作符访问的fun方法。

一、执行函数

让我们执行如下语句:

这段语句的意思是:将fun(0)赋值给a,并调用a。这段语句的结果就是:

1、输出undefined;(因为赋值语句中没有给外层fun函数第二个参数,而输出语句输出的是第二个参数,所以输出结果是undefined)

2、返回一个对象,该对象包含一个fun方法。该方法接受一个输入参数m,返回一个函数fun()。这个内层函数有两个参数,第一个参数是输入参数m,第二个参数是外层函数的第一参数0。

注意:如果调用这个方法,那么相当于再执行一次外层函数fun,不过这次给fun输入了两个参数m,0。

 二、第一次调用方法

那么我们就来调用该方法。语句如下:

因为调用a之后,a相当于是一个包含fun方法的对象,即{fun:function(m){return fun(m,0);}}。

那么a.fun(1)相当于是调用对象a的fun方法,并传入参数1。该方法是一个函数function(m){return fun(m,0)},该函数又返回一个函数fun(m,0)。

所以调用a.fun(1)相当于是执行函数fun(1,0)。执行结果就是:

1、输出0(此时第二个参数为0);

2、返回一个对象,该对象包含一个fun方法。该方法接受一个输入参数m,返回一个函数fun()。这个内层函数有两个参数,第一个参数是输入参数m,第二个参数是外层函数的第一参数1。

调用a的fun(1)方法后,此时a.fun(1)相当于是一个包含fun方法的对象。即{fun:function(m){return fun(m,1);}}。

三、第二次调用方法

那么我们就来调用a.fun(1)的fun方法。语句如下:

a.fun(1).fun(2)相当于是调用a.fun(1)这个对象的fun方法,并传入参数2。该方法是一个函数function(m){return fun(m,1);}

所以调用a.fun(1).fun(2)相当于是执行函数fun(2,1)。执行结果就是:

1、输出1(此时第二个参数为1);

2、返回一个对象。该对象包含一个fun方法。该方法接受一个输入参数m,返回一个函数fun()。这个内层函数有两个参数,第一个参数是输入参数m,第二个参数是外层函数的第一参数2。

调用a.fun(1)的fun(2)方法后,此时a.fun(1).fun(2)相当于是一个包含fun方法的对象。即{fun:function(m){return fun(m,2);}}

四、第三次调用方法

那么我们就来调用a.fun(1).fun(2)的fun方法。语句如下:

a.fun(1).fun(2).fun(3)相当于是调用a.fun(1).fun(2)的fun方法,并传入参数3。该方法是一个函数function(m){return fun(m,2);}。

所以调用a.fun(1).fun(2).fun(3)相当于是执行fun(3,2)。执行结果如下:

1、输出2(此时第二个参数是2);

2、返回一个对象。该对象的fun方法接受一个输入参数m,返回一个函数fun()。这个内层函数有两个参数,第一个是输入参数m,第二个参数是外层函数的第一个参数3。

这种调用方式称为链式调用

我们再看如下代码:

由上可知,调用a,a相当于是一个对象{fun:function(m){return fun(m,0);}}。

所以a.fun(1)相当于执行fun(1,0)。所以输出0。然后返回对象{fun:function(m){return fun(m,1);}}。

所以a.fun(2)相当于执行fun(2,0)。所以输出0。然后返回对象{fun:function(m){return fun(m,2);}}。

所以a.fun(3)相当于执行fun(3,0)。所以输出0。然后返回对象{fun:function(m){return fun(m,3);}}。

posted @ 2017-06-25 21:14  海盗洁哥  阅读(1542)  评论(0编辑  收藏  举报