Skip to content

递归

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

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

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

js
var anotherFactorial = factorial;
factorial = null;
console.log(anotherFactorial(4)); // 报错

以上代码先把factorial函数保存到变量anotherFactorial中,然后将factorial变量设置为null,结果指向原始函数的引用只剩下一个。但接下来调用anotherFactorial时,必须执行factorial,而此时factorial已经不再是函数,所以会导致报错。在这种情况下,我们可以使用arguments.callee可以解决这个问题。

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

js
function factorial(num) {
	if(num <= 1) {
		return 1;
	}else {
		return num * arguments.callee(num - 1);
	}
}

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

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