递归.md

递归

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

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

这是一个经典的递归阶乘函数。虽然这个函数表面看来没什么问题,但下面的代码却可能导致它出错。

1
2
3
var anotherFactorial = factorial; 
factorial = null;
alert(anotherFactorial(4)); //出错!

原始函数中有对factorial的引用,将factorial=null后factorial被销毁了,所以执行这个引用后找不到。

使用arguments.callee

稳妥的递归用法使用arguments.calleearguments是一个对应于传递给函数的参数的类数组对象,arguments.callee指向正在执行的函数指针。

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

但是在严格模式下,不能访问arguments.callee ,使用命名函数表达式实现。

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

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