最近在codewars上做一些JS任务,遇到了这个任务Tail recursion with trampoline。这里我们需要创建 thunk 函数和 trampoline 函数来摆脱恼人的 RangeError: Maximum call stack size exceeded。所以我尝试了这段代码:
function thunk(fn) {
let args = [...arguments].slice(1, arguments.length);
return function () {
return fn.apply(null, args);
};
};
function trampoline(thunk) {
while (typeof thunk === 'function') {
thunk = thunk();
}
return thunk;
}
function isEven(n) {
let arg = n;
function _isEven() {
return (arg === 0 ? true : isOdd(arg - 1));
};
return trampoline(thunk(_isEven, n));
}
function isOdd(n) {
let arg = n;
function _isOdd() {
return (arg === 0 ? false : isEven(arg - 1));
};
return trampoline(thunk(_isOdd, n));
}
这没有用,仍然有 RangeError。但是在我将 console.log() 添加到 _isOdd 或 _isEven 之后,它不会抛出错误并通过所有测试。像这样:
function thunk(fn) {
let args = [...arguments].slice(1, arguments.length);
return function () {
return fn.apply(null, args);
};
};
function trampoline(thunk) {
while (typeof thunk === 'function') {
thunk = thunk();
}
return thunk;
}
function isEven(n) {
let arg = n;
function _isEven() {
console.log();
return (arg === 0 ? true : isOdd(arg - 1));
};
return trampoline(thunk(_isEven, n));
}
function isOdd(n) {
let arg = n;
function _isOdd() {
return (arg === 0 ? false : isEven(arg - 1));
};
return trampoline(thunk(_isOdd, n));
}
我理解错误并重写了代码,但不明白为什么添加console.log()时它会起作用。