尾调用优化与连续传递风格:写出永不栈溢出的递归
利用 ES6 尾调用优化(TCO)原理,结合 CPS 变换,将递归转化为常数栈空间,绕过调用栈限制。 · 难度:入门 · +10XP
尾调用优化与连续传递风格:写出永不栈溢出的递归
大多数教程只提尾递归,却从未解释其底层机制和局限性。本课将深入 V8 引擎对尾调用优化的支持现状(严格模式下的实现),并教授如何通过连续传递风格(CPS)将任何递归函数转换为尾递归形式。你将手动实现一个 trampoline 技术作为标准递归的安全替代,并理解为何在某些场景下 TCO 无法生效,以及如何用蹦床函数(bounce)优雅地解决。
function factorial(n, acc = 1) {
if (n === 0) return acc;
return factorial(n - 1, n * acc); // 尾递归
}
// Trampoline 技术(兼容所有引擎)
function trampoline(fn) {
return function(...args) {
let result = fn(...args);
while (typeof result === 'function') {
result = result();
}
return result;
};
}
const safeFactorial = trampoline(function f(n, acc = 1) {
return n === 0 ? acc : () => f(n - 1, n * acc);
});