所谓递归:就是函数调用函数本身

在数学中,常常使用到阶乘,累加之类的,这就是经典的递归函数了

例如:输入一个数,要计算这个数的阶乘

 

首先来分析一下:要计算阶乘,首先我们要确定阶乘的输入数是多少,例如是 n;

那么:计算公式是什么呢?

假设值为 f(n) , 那么

f(n) = 1*2*3*4*5*6*7*8*9*10*.....*n;

这就难办了,要一直乘法,何时是个头呢?

再分析一下:f(n) = f(n-1)*n  只要n>1,算法永远成立

好了,那我们就开始来算吧,从后往前推,知道n=1 为止,这个计算就完成了

我们不需要去考虑要写多少算式,因为这是计算机帮我们写,不需要关心这些;只管照着这个逻辑去做就行

 

 1     <script>
 2         function jiecheng(n) {
 3             if (n == 1) {
 4                 return 1;
 5             } else {
 6                 return jiecheng(n - 1) * n;
 7             }
 8         }
 9 
10         var jieguo1 = jiecheng(5);
11         var jieguo2 = jiecheng(8);
12         console.log(jieguo1);
13         console.log(jieguo2);
14     </script>

 

 

增加一个新函数,使用新函数调用,仍然没有问题

 1     <script>
 2         function jiecheng(n) {
 3             if (n == 1) {
 4                 return 1;
 5             } else {
 6                 return jiecheng(n - 1) * n;
 7             }
 8         }
 9 
10         var jiecheng1 = jiecheng; // 创建一个新函数,继续调用,仍然没有问题
11         var jieguo1 = jiecheng1(5);
12         var jieguo2 = jiecheng1(8);
13         console.log(jieguo1);
14         console.log(jieguo2);
15     </script>

 

对旧函数进行清空,然后再调用;

    <script>
        function jiecheng(n) {
            if (n == 1) {
                return 1;
            } else {
                return jiecheng(n - 1) * n;
            }
        }

        var jiecheng1 = jiecheng; // 创建一个新函数,继续调用,仍然没有问题
        jiecheng = null;          // 改变原先函数的指向,则会出错
        var jieguo1 = jiecheng1(5);
        var jieguo2 = jiecheng1(8);
        console.log(jieguo1);
        console.log(jieguo2);
    </script>

 

原因:在函数的内部,我们仍然使用原来函数的函数名,即原来的指针;但是现在指针指向null 了,所以报错

 

解决这个问题,我们会用到另外一个指针函数:arguments.callee   , 表示指向当前运行函数的指针;即当前正在运行的函数为sum,那么它指向sum ;如果当前运行的函数是hehehe,那么它指向heheh,它是一个变化的指针

 

修改之后,我们得到的代码如下:这样,即使改变了原先函数的指向,也不会出现错误了

 1     <script>
 2         function jiecheng(n) {
 3             if (n == 1) {
 4                 return 1;
 5             } else {
 6                 return arguments.callee(n - 1) * n;
 7             }
 8         }
 9 
10         var jiecheng1 = jiecheng; // 创建一个新函数,继续调用,仍然没有问题
11         jiecheng = null; // 改变原先函数的指向
12         var jieguo1 = jiecheng1(5);
13         var jieguo2 = jiecheng1(8);
14         console.log(jieguo1);
15         console.log(jieguo2);
16     </script>

 

 

但是,在严格模式下,js 不允许使用 arguments.callee ,我们再来看另外一种情况

 

 1    <script>
 2         var jiecheng = (function f1(n) {
 3             if (n == 1) {
 4                 return 1;
 5             } else {
 6                 return f1(n - 1) * n;
 7             }
 8         });
 9 
10         var jiecheng1 = jiecheng; // 创建一个新函数,继续调用,仍然没有问题
11         jiecheng = null; // 改变原先函数的指向
12         var jieguo1 = jiecheng1(5);
13         var jieguo2 = jiecheng1(8);
14         console.log(jieguo1);
15         console.log(jieguo2);
16     </script>

 

这里,使用命名表达式来完成,即使把 jiecheng() 赋值为null 了,也不影响命名表达式内部的指针,所以能够执行

 

posted on 2018-04-07 19:22  huanying2015  阅读(589)  评论(0编辑  收藏  举报