JavaScript 如何做函数组合
早上出门前,你会先穿袜子再穿鞋,这个“先穿A再穿B”的固定步骤,就和编程里的函数组合是一个道理——把多个简单的小功能按顺序串起来,最后得到一个你需要的结果,不用每次都重复写步骤。
什么是函数组合?
函数组合不是什么复杂的代码,简单说就是“把两个或多个函数拼在一起,让前一个函数的输出,自动变成后一个函数的输入,最后得到想要的结果”。举个生活化的例子:你买了一杯冰美式(第一个函数:买咖啡),加了两勺糖(第二个函数:加糖),再插一根吸管(第三个函数:插吸管),这三个小操作按顺序做,最后得到的是“可以直接喝的甜冰美式”,这个“串起来操作”的过程,就是函数组合。

放在代码里,比如你有两个简单函数:一个是把名字的首字母大写(upperFirst),另一个是在名字后面加“同学”后缀(addTitle)。如果不用组合,你得先写addTitle(upperFirst("张三"))——先把“张三”变成“张三”(首字母本来就大写),再变成“张三同学”;用组合的话,你可以把这两个函数拼起来,变成一个新函数,直接传“张三”就得到结果,不用每次嵌套写。
手写最简单的函数组合
不用复杂工具,自己就能写个小函数实现组合。假设我们只有两个函数,比如第一个函数是“给数字加5”(addFive),第二个函数是“给数字乘2”(multiplyByTwo),我们要做的是“先加5再乘2”,而不是反过来。
写一个叫compose的小工具:
`javascript
function compose(func1, func2) {
// 返回一个新函数,这个新函数会接收一个参数
return function(x) {
// 先执行func1,把结果传给func2
return func2(func1(x));
};
}
`
测试一下:const calculate = compose(addFive, multiplyByTwo); 调用calculate(3),先算3+5=8,再算8*2=16,结果就是16,完美符合“先加后乘”的要求。这个小工具就是函数组合的核心逻辑——把前一个函数的输出,当后一个的输入。
多函数组合和实际场景用法
刚才的compose只能拼两个函数,要是有三个以上的功能,比如“先加5→乘2→再减3”,也能扩展,或者用JS自带的reduce(可以理解为“把数组里的元素按顺序攒成一个结果”)来写通用的多函数组合:
`javascript
function compose(...funcs) {
return function(x) {
return funcs.reduceRight((current, func) => func(current), x);
};
}
`
这里的reduceRight是从右往左执行函数——因为函数组合的顺序是“先写的函数先执行”,比如compose(funcA, funcB, funcC)就是先执行funcA,再B,再C,用reduceRight就能按这个顺序传值。
实际用的时候,比如处理用户的昵称:用户输入的昵称可能有空格、大小写,你要做的是“去掉首尾空格→转全小写→加前缀‘用户:’”,这三个功能分别对应三个小函数,用组合拼起来后,只要传用户输入,就能直接得到规范的昵称。比如:
`javascript
const trim = str => str.trim();
const toLower = str => str.toLowerCase();
const addPrefix = str => 用户:${str};
// 组合三个函数
const formatNickname = compose(addPrefix, toLower, trim);
// 测试:用户输入 " 小 明 "
console.log(formatNickname(" 小 明 ")); // 输出 "用户:小 明"
`
是不是比每次写三个嵌套的函数清爽多了?
注意一个小细节
函数组合的顺序很重要,就像刚才穿袜子和穿鞋,要是先穿鞋再穿袜子,肯定不对。代码里如果把组合的函数顺序写反,结果就会错——比如刚才的昵称例子,要是把组合写成compose(trim, toLower, addPrefix),就会先加前缀,再转小写,最后去空格,得到的是“用户:小 明”(前缀里的大写U不会被转),就不符合预期了。
函数组合本质是“把零散的小功能按顺序组装成一个新工具”,不管是处理数据还是写重复的步骤,用它都能让代码更简洁、好维护,不用每次都重复写相同的嵌套逻辑,这就是它最实用的地方。