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

  1. function factorial (num) {
  2. if (num <= 1) {
  3. return 1;
  4. } else {
  5. return num * factorial(num-1)
  6. }
  7. }

递归问题

  1. function factorial (num) {
  2. if (num <= 1) {
  3. return 1;
  4. } else {
  5. return num * factorial(num-1);
  6. }
  7. }
  8. let anotherFactorial = factorial
  9. console.log(anotherFactorial(4)) // 24
  10. factorial = null
  11. console.log(anotherFactorial(4)) // TypeError: factorial is not a function

当 factorial 为赋值为 null 之后,在此执行 anotherFactorial 的时候,由于函数内部又调用了 factorial,所以报错。

tips: 函数名仅为指向函数的指针,并不是函数本身。因此 factorial 被赋值为 null 的时候,其原来所指向的函数并没有销毁,因为 anotherFactorial 这个函数名也指向了这个函数。

针对这种情况,可以有两种方式在解决

  • 使用 arguments.callee

  • 使用命名函数表达式

  1. function factorial (num) {
  2. if (num <= 1) {
  3. return 1;
  4. } else {
  5. return num * arguments.callee(num-1)
  6. }
  7. }
  8. let anotherFactorial = factorial;
  9. console.log(anotherFactorial(4)); // 24
  10. factorial = null;
  11. console.log(anotherFactorial(4)); // 24
  1. let factorial = (function test (num) {
  2. if (num <= 1) {
  3. return 1;
  4. } else {
  5. return num * test(num-1);
  6. }
  7. })
  8. let anotherFactorial = factorial;
  9. console.log(anotherFactorial(4)); // 24
  10. factorial = null;
  11. console.log(anotherFactorial(4)); // 24

tips:(function(){}) 也是函数表达式中的一种。函数名字可指定,也可以不指定。 (function test() {}) 这种形式去定义了函数有一个特点,就是不会再外部作用域中创建一个变量。因此外部并不能通过 test() 去调用函数。