代码如下
function tco(f) {
var value;
var active = false;
var accumulated = [];
return function accumulator() {
accumulated.push(arguments);
if (!active) {
active = true;
while (accumulated.length) {
value = f.apply(this, accumulated.shift());
}
active = false;
return value;
}
};
}
var sum = tco(function ff(x, y) {
if (y > 0) {
return sum(x + 1, y - 1)
}
else {
return x
}
});
sum(1, 100000)
// 100001
上面的代码的执行栈图
首先来说下变量value
、active
、accumulated
的作用
value
:保存最终递归结果,在递归期间一直是undefined
。
accumulated
:用来结束while循环。
active
:栈帧释放判断条件。
我在学习这段代码时,有一个疑惑,while循环执行一次后就会因不满足条件而退出循环,那么可不可以用if
代替呢?答案是否。因为while
会一直循环而不是只执行一次,虽然 accumulator
函数代码看起来是这样的。其原因是 第二个accumulator
帧在执行accumulated.push(arguments);
时使accumulated.length
为真,当会返回到第一个accumulator
帧时就会因满足条件而继续循环。最后当执行到return x
时就不会再创建第二个accumulator
帧,ff
返回出栈,第一个accumulator
因不满足条件而退出循环返回递归结果value
出栈,整个递归过程就结束了。
网友评论