js 递归怎么实现
递归的基本概念
递归是一种在函数内部调用自身的技术。它通常用于解决可以分解为相似子问题的问题,如阶乘、斐波那契数列、树形结构遍历等。
递归的实现步骤
定义一个递归函数需要明确两个关键部分:基线条件(Base Case)和递归条件(Recursive Case)。基线条件是递归终止的条件,递归条件是函数调用自身的条件。

function recursiveFunction(parameters) {
// 基线条件:终止递归
if (baseCaseCondition) {
return baseCaseResult;
}
// 递归条件:调用自身
return recursiveFunction(modifiedParameters);
}
递归的经典示例
计算阶乘
阶乘的递归实现是一个典型的例子。n的阶乘(n!)可以表示为n * (n-1)!,基线条件是0! = 1。

function factorial(n) {
if (n === 0) {
return 1; // 基线条件
}
return n * factorial(n - 1); // 递归条件
}
console.log(factorial(5)); // 输出: 120
斐波那契数列
斐波那契数列的第n项是前两项之和,基线条件是第0项为0,第1项为1。
function fibonacci(n) {
if (n <= 1) {
return n; // 基线条件
}
return fibonacci(n - 1) + fibonacci(n - 2); // 递归条件
}
console.log(fibonacci(6)); // 输出: 8
递归的注意事项
- 栈溢出:递归可能因为调用层级过深导致栈溢出。可以通过尾递归优化或改用循环(迭代)来避免。
- 性能问题:某些递归(如斐波那契数列的朴素递归)会重复计算,效率低下。可以使用记忆化(Memoization)优化。
- 尾递归优化:某些JavaScript引擎支持尾递归优化,但需确保递归调用是函数的最后一步操作。
尾递归优化示例
尾递归优化可以避免栈溢出,但需要代码符合尾调用规范。
function factorialTailRecursive(n, accumulator = 1) {
if (n === 0) {
return accumulator;
}
return factorialTailRecursive(n - 1, n * accumulator);
}
console.log(factorialTailRecursive(5)); // 输出: 120
递归与迭代的选择
递归代码通常更简洁,但可能带来性能问题。对于简单问题或明确需要递归的场景(如树遍历),递归是合适的选择。对于性能敏感的场景,迭代可能是更好的选择。






