实现compose函数:我的递归写法为何无法正常工作?
你的递归compose函数错误原因分析
核心问题:未将参数v传递给递归生成的函数
你的递归实现里,当函数列表长度≥2时,执行了:
return fns[0](compose(...fns.slice(1)));
这里compose(...fns.slice(1))返回的是一个待执行的闭包函数,但你直接把这个函数作为参数传给了fns[0],而不是调用这个函数并传入当前的v值。
举个实际调用的例子,假设调用compose(fn2, fn1)(10):
- 第一次进入
composed函数,fns是[fn2, fn1],满足长度≥2的条件 - 执行
fn2(compose(fn1)),但compose(fn1)返回的是一个函数,不是fn1(10)的计算结果 - 最终
fn2接收的参数是一个函数,而非预期的fn1(10)返回值,自然无法得到正确结果
修正后的递归实现
只需要在递归调用后加上(v),把当前参数传递进去即可:
function compose(...fns) { return function composed(v) { if (fns.length >= 2) { // 先执行后续函数组合并传入v,再把结果传给第一个函数 return fns[0](compose(...fns.slice(1))(v)); } else { // 只剩一个函数时,直接调用它并传入v return fns[0](v); } } }
和循环实现的逻辑对比
你的循环实现逻辑是正确的:
function compose(...fns) { return function(v) { for (let fn of fns) { v = fn(v); } return v; } }
它的执行流程是:
- 初始v为传入的原始参数
- 遍历函数列表,依次用当前v调用每个函数,将返回值更新为新的v
- 最终返回经过所有函数处理后的v
修正后的递归实现和这个逻辑完全一致:每次递归处理剩余的函数列表,把v传递进去得到结果,再交给当前第一个函数处理。
内容的提问来源于stack exchange,提问作者mark
相关产品推荐
相关产品推荐

