JavaScript函数组合:如何替换并增强已有库函数
当然可以用函数组合实现,无需创建命名函数
完全不用非得写一个新的命名函数来替换,函数组合就是干这个事儿的!不过这里要注意一下执行顺序的问题——你想要先跑原函数logThis,再跑额外函数,这其实更贴近「管道(pipe)」的逻辑(从左到右依次执行),而传统的compose通常是从右到左执行的,咱们一步步来:
方法一:自定义顺序执行的组合函数(兼容所有JS环境)
先写一个简单的工具函数,让它能按传入的顺序依次执行所有函数,还能传递参数:
// 定义一个sequence函数,按传入顺序执行所有函数 function sequence(...fns) { return function(...args) { fns.forEach(fn => fn(...args)); }; } // 你的原函数 function logThis() { console.log('this'); } // 要追加的额外函数 function logThat() { console.log('that'); } // 直接把原函数替换成组合后的新函数 logThis = sequence(logThis, logThat); // 测试一下,调用后会先打'this'再打'that' logThis();
如果你的原函数有返回值,还想让后面的函数用到这个返回值,可以改成管道式的组合函数:
// pipe函数:前一个函数的返回值作为后一个函数的输入 function pipe(...fns) { return function(...args) { return fns.reduce((prevResult, currentFn) => currentFn(prevResult), ...args); }; } // 带返回值的原函数 function logThis() { console.log('this'); return '来自logThis的结果'; } // 接收前一个函数返回值的额外函数 function logThat(value) { console.log(`that,收到的值:${value}`); } logThis = pipe(logThis, logThat); logThis(); // 先打'this',再打'that,收到的值:来自logThis的结果'
方法二:用原生pipe函数(现代JS环境)
ES2023之后JS原生支持了Function.prototype.pipe,可以直接链式组合,代码更简洁:
function logThis() { console.log('this'); } function logThat() { console.log('that'); } // 直接把原函数替换成组合后的版本 logThis = logThis.pipe(logThat); logThis(); // 同样先'this'后'that'
关于传统compose的小提醒
传统函数式编程里的compose是从右到左执行的,比如compose(f, g)会先跑g再跑f。如果要用这种compose实现你的需求,得把函数顺序反过来:
// 传统compose的实现 function compose(...fns) { return function(...args) { return fns.reduceRight((result, fn) => fn(result), ...args); }; } // 要先跑logThis再跑logThat,得把logThat放前面 logThis = compose(logThat, logThis); logThis(); // 还是先'this'后'that'
总之,核心就是:函数组合完全能实现你的需求,不用非得创建命名函数,只要搞清楚组合函数的执行顺序就行~
内容的提问来源于stack exchange,提问作者Dennis Bauszus
相关产品推荐
相关产品推荐

