JavaScript 中的尾递归和普通递归的主要区别在于函数的调用栈大小。普通递归会在每次递归调用时在调用栈中创建一个新的堆栈帧,而尾递归则会重用当前堆栈帧。
这意味着在使用尾递归时,函数调用栈的大小不会随着递归深度的增加而增加。这可以避免栈溢出错误,并且可以提高代码的性能。
下面是一个使用普通递归的示例,该函数计算斐波那契数列的第 n 项:
function fibonacci(n) {
if (n <= 1) {
return n;
} else {
return fibonacci(n - 1) + fibonacci(n - 2);
}
}
console.log(fibonacci(10)); // 55
这个函数使用普通递归实现,每次递归调用都会在调用栈中创建一个新的堆栈帧,导致调用栈大小增加。对于较大的 n 值,这可能会导致栈溢出错误。
下面是一个使用尾递归的示例,该函数计算斐波那契数列的第 n 项:
function fibonacciTail(n, a = 0, b = 1) {
if (n === 0) {
return a;
} else {
return fibonacciTail(n - 1, b, a + b);
}
}
console.log(fibonacciTail(10)); // 55
这个函数使用尾递归实现,每次递归调用都会重用当前堆栈帧,而不是创建一个新的堆栈帧。这样可以避免调用栈大小增加,从而避免栈溢出错误。