递归

递归函数是在一个函数通过名字调用自身的情况下构成的。以下为经典的递归阶乘函数。

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

这个函数看起来没什么问题,但是以下代码却会导致其出错。

var anotherFactorial = factorial;
factorial = null;
alert(anotherFactorial(4))  //报错

  因为,原本把factorial()函数保存在变量anotherFactorial中,后又将factorial赋值为null,指向原始函数的引用只剩下一个。调用anotherFactorial()时,由于必须执行factorial(),而factorial已经不再是函数,所以会报错。这种情况下,使用arguments.callee可以解决。

  arguments.callee是一个指向正在执行的函数的指针,因此可以用它来实现对函数的递归调用。

var factorial = (function f(n){
      if(n <=1 ){
        return 1;
    }else{
        return n * arguments.callee(n-1);
    }
})

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

      在严格模式下,ES5禁止使用arguments.callee(),不能通过脚本访问arguments.callee,访问这个属性会导致错误。当一个函数必须调用自身的时候,避免使用,要么给函数表达式一个名字,要么使用一个函数声明。

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

创建了一个名为f()的命名函数表达式,然后将它赋值给变量factorial。即便把函数赋值给了另一个变量,函数的名字 f 仍然有效,递归照样正确完成,这种方式在严格模式和非严格模式下都行得通。

原文地址:https://www.cnblogs.com/coldfishdt/p/6532991.html