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(x, y) {
if (y > 0) {
return sum(x + 1, y - 1)
}
else {
return x
}
});
sum(1, 100000)
// 100001
这段代码的理解关键:
- value和active和accmulated=[]是三个闭包变量,所有sum方法进来都会与这三个变量交互。
- 调用栈里至多运行着accumulator并在里面进入一次sum方法。
- 首先传入的是[1,100],进入while循环里,并得到一次sum(2,99)
此时 accumulated = [] value = undefined active = true
- 但是进入sum(2,99)后,他是进不了!active,但它还是放了参数进了accmulated数组,然后这个sum就执行完了。
此时 accumulated = [2,99] value = undefined active = true
- 这个改动导致最外层的函数while循环又可以动起来了(accumulated不为空)。如此循环。
- 也就是说,第一次调用的accmulator从头运行到尾,而不断创建的sum函数,只运行了accumulated.push(arguments)这一句。