递归

104 阅读1分钟

做前端开发已经好几年了,技术与工作年限不匹配,自查,将知识点整理出来,自我完善,也希望能帮助到大家。

本内容是参考《JavaScript高级程序(第3版)》学习。

递归

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

function factorial (num) {
  if (num <= 1) {
    return 1;
  } else {
    return num * factorial(num - 1);
  }
};
​
// 这是一个经典的递归阶乘函数。虽然这个函数表面看来没什么问题,但下面代码可能导致它出错。
var anotherFactorial = factorial'
factorial = null;
alert(anotherFactorial(4));   // 出错。
​
// 这种情况下,使用arguments.callee 可以解决这个问题。  callee是一个指向正在执行的函数的指针,因此可以用它来实现对函数的递归调用。
function factorial (num) {
  if (num <= 1) {
    return 1;
  } else {
    return num * arguments.callee(num - 1);
  }
}
​

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

但在严格模式下,不能通过脚本访问 arguments.callee,访问这个属性会导致错误。不过,可以使用命名函数表达式来达成相同的结果。

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

这种方式在严格模式和非严格模式下都行得通。


个人总结

什么是递归

在JavaScript中,递归,就是函数自己调用自己。是循环运算的一种算法模式,和while循环模式挺相似的。把问题一层一层的分解下去,但是不能无限循环下去。

长应用解决一些数学运算,比如阶乘函数,幂函数和斐波那契数等。

递归调用注意点

递归调用的过程;必要的终止条件(出口)

在没有限制的情况下,递归会无终止的自身调用,导致程序的崩溃(爆栈,或程序无限运行导致假死状态),所以在递归运算中要结合条件语句进行控制,只有在某个条件成立时才允许执行递归,否则不允许调用自身。