码迷,mamicode.com
首页 > 其他好文 > 详细

递归函数详解

时间:2018-01-22 14:10:55      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:span   函数表达式   产生   function   factorial   asc   func   错误   运行   

1、什么是递归函数?

递归函数就是在一个函数通过名字调用自身的情况下构成的,

如下所示:我们用递归实现阶乘

    var factorial = function (num) {
        if (num <= 1) {
            return 1;
        } else {
            return num * factorial(num - 1);
        }
    }

2、如何实现递归函数?

(1)先写一层的情况。上面所示的递归阶乘我们就可以先思考num参数乘num-1的情况。

(2)抽象递归参数。在递归函数中,如何将下一层关联起来就需要抽象参数来进行解决,参数的个数根据情况而定。

(3)找到突破点。为什么要找一个突破点?在js中你会发现很少有人写递归,因为不注意就会造成死循环。必须记住递归函数是自己调用自己,某种情况(这种情况肯定存在)不调用自己。在上面的递归函数中num<=1就是一个突破点。

3、上述代码存在的问题

    var anotherfactorial = factorial;
    factorial = null;
    console.log(anotherfactorial(3)); // factorial is not a function(出错)

为什么会出错呢?

以上代码先把factorial函数保存在变量anotherfactorial中,然后将factorial赋值为null。导致的结果指向原始函数的引用只剩下一个。但是接下来调用anotherfactorial时,由于必须执行factorial函数,而factorial这时候已经赋值为null了,所以就会导致错误。

那么如何解决这个问题呢?

在ECMAScript提供了arguments.callee可以解决这个问题。arguments.callee是一个指向正在执行的函数(anotherfactorial)的指针,因此可以用它来实现对函数的递归调用。例如上述代码我们就可以这样写:

    var factorial = function (num) {
        if (num <= 1) {
            return 1;
        } else {
            return num * arguments.callee(num - 1);
        }
    }
    var anotherfactorial = factorial;
    factorial = null;
    console.log(anotherfactorial(3)); // 6

通过使用arguments.callee代替函数名,可以确保无论怎样调用函数都不会出问题。因此在使用递归函数时,使用arguments.callee总比使用函数名更保险。

但是在严格模式下,不能直接访问arguments.callee,并且会导致错误。所以产生了终极解决方案,使用命名函数表达式来达成相同的效果。例如:

    var factorial = (function f(num) {
        if (num <= 1) {
            return 1;
        } else {
            return num * f(num - 1);
        }
    });
    var anotherfactorial = factorial;
    factorial = null;
    console.log(anotherfactorial(3)); // 6

在以上代码中创建了一个名为f的命名函数表达式,避免了出现arguments.callee。然后将它赋值给变量factorial。即使把函数赋值给另一个变量,函数的名字f仍然有效,所以递归调用照样能正确完成,而且这种方法在严格模式和非严格模式下都能运行。

递归函数详解

标签:span   函数表达式   产生   function   factorial   asc   func   错误   运行   

原文地址:https://www.cnblogs.com/onebox/p/8328486.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!