MST
星途 面试题库

面试题:JavaScript 函数调用的递归优化

有一个递归函数`function factorial(n) { if (n <= 1) return 1; return n * factorial(n - 1); }`,当计算较大数字的阶乘时,容易导致栈溢出。请使用尾递归优化技术对该函数进行改写,同时阐述尾递归在JavaScript函数调用优化中的原理和优势。
23.1万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

尾递归优化后的代码

function factorialHelper(n, acc = 1) {
    if (n <= 1) {
        return acc;
    }
    return factorialHelper(n - 1, n * acc);
}

function factorial(n) {
    return factorialHelper(n);
}

尾递归原理

尾递归是指在函数的最后一步调用自身,并且该调用是函数的最后一个操作。在尾递归中,递归调用返回的值直接作为当前函数的返回值,而不需要再进行额外的计算。这样,JavaScript引擎可以优化尾递归,通过复用当前栈帧来避免栈溢出问题。因为在尾递归的情况下,函数执行到最后一步时,已经没有其他操作需要在当前栈帧中完成,所以可以直接重用当前栈帧来执行下一次递归调用,而不需要为每次递归调用创建新的栈帧。

尾递归优势

  1. 避免栈溢出:对于深度递归的场景,传统递归由于不断创建新的栈帧,当递归深度过大时,很容易导致栈溢出错误。而尾递归通过复用栈帧,理论上可以支持无限深度的递归调用,大大提升了程序的稳定性和可靠性。
  2. 提高性能:减少栈帧的创建和销毁开销,在性能上有一定提升。因为栈帧的创建和销毁需要消耗系统资源,尾递归避免了这种不必要的开销,使得程序执行效率更高。