我正在尝试重新实现 redux compose函数,而不是使用 reduce
我使用 for 循环,这是我的代码:
function compose(...funcs) {
if (funcs.length === 0) {
return (arg) => arg;
}
if (funcs.length === 1) {
return funcs[0];
}
let result;
for (let i = funcs.length - 1; i > -1; i--) {
result = result
? (...args) => funcs[i](result(...args))
: (...args) => funcs[i](...args);
}
return result;
}
// test
function fn1(x) {
return x + 1;
}
function fn2(x) {
return x * 10;
}
function fn3(x) {
return x - 1;
}
console.log(compose(fn3, fn2, fn1)(10)); // 109
由于 (10 + 1) * 10 - 1 是 109,预计会记录 109,但是它给了我这样的错误:
RangeError: Maximum call stack size
看起来我正在做一些递归,但我所做的只是一个 for 循环,不确定我的代码问题出在哪里?
最佳答案
我认为问题就像下面的例子:
a = () => 2;
a = () => 3 * a();
console.log(a);
// this prints () => 3 * a() in console
// so when you call a(), it will call 3 * a(), which will again call 3 * a() and so on
// leading to infinite recursion
我的解决方案与使用基于此引用链接的bind
函数略有不同:https://stackoverflow.com/a/6772648/4688321 .
我认为bind
创建了函数result
的新副本并将其绑定(bind)到一个新对象。不使用 bind
会导致递归,因为代码会像上面的示例一样,result
调用 result
。
function compose(...funcs) {
if (funcs.length === 0) {
return (arg) => arg;
}
if (funcs.length === 1) {
return funcs[0];
}
let result;
for (let i = funcs.length - 1; i > -1; i--) {
if (i == funcs.length - 1)
result = (...args) => funcs[i](...args);
else {
let temp = result.bind({});
result = (...args) => funcs[i](temp(...args));
}
}
return result;
}
// test
function fn1(x) {
console.log("fn1");
return x + 1;
}
function fn2(x) {
console.log("fn2");
return x * 10;
}
function fn3(x) {
console.log("fn3");
return x - 1;
}
//console.log(compose(fn3, fn2, fn1));
let ret = compose(fn3, fn2, fn1);
console.log(ret(10)); // 109
关于javascript - 实现 redux compose 函数但得到 RangeError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70784623/