尾调用优化(TCO)是引擎复用调用帧以避免栈溢出的机制:尾调用指函数最后一步直接返回另一函数调用结果,无后续运算;普通递归因每调用压一帧致爆栈,而尾递归+TCO可重用帧、降空间复杂度至O(1)。
尾调用优化(Tail Call Optimization,TCO)是 JavaScript 引擎在特定条件下对函数尾调用进行的内存与执行效率优化:当一个函数的最后一步是调用另一个函数(或自身),且该调用的返回值直接作为当前函数返回值时,引擎可复用当前函数的调用帧,避免新增栈帧。
尾调用不是“在函数末尾调用”,而是“调用后不再做任何事”。关键看是否要基于调用结果继续计算:
return factorial(n - 1, n * acc);(直接返回,无后续运算)return n * factorial(n - 1);(需等子调用返回后再乘,必须保留当前帧)每次函数调用都会在调用栈中压入一个新帧,保存局部变量、参数和返回地址。深度递归(如计算 factorial(10000))会累积上万帧,超出引擎栈深限制(通常几千),触发 RangeError: Maximum call stack size exceeded。
当递归调用处于尾位置,且引擎启用 TCO(如 Safari 已支持,Chrome/V8 在严格模式下曾尝试但未默认启用),它可将递归“转为循环”:
n 和 acc),跳回函数开头O(n) 降至 O(1)
例如,正确尾递归阶乘:
function factorial(n, acc = 1) {TCO 并非所有环境都可靠:
hrome、Firefox)出于实现复杂性和调试考量,未默认开启