最近我在代码战争上做了一些JS任务,遇到了这个任务蹦床的尾递归。在这里,我们需要创建thunk函数和蹦床函数来消除烦人的东西RangeError:超过了最大调用堆栈大小。所以我尝试了这个代码:
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((添加到_isAdd或_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((.时它能工作
此任务的正确解决方案如下:
function thunk(fn /*, args */) {
return fn.bind.apply(fn, arguments);
}
function trampoline(thunk) {
while(typeof (thunk=thunk()) == "function");
return thunk;
}
function _isOdd(n) {
return (n === 0 ? false : thunk(_isEven, n - 1));
}
function _isEven(n) {
return (n === 0 ? true : thunk(_isOdd, n - 1));
}
function isEven(n) {
return trampoline(thunk(_isEven, n));
}
function isOdd(n) {
return trampoline(thunk(_isOdd, n));
}