JavaScript函数柯里化和组合是函数式编程中非常实用的两项技术,它们可以帮助我们把复杂的逻辑拆分成更小的单元,提升代码的复用性和可读性,在很多前端框架的工具函数设计中都有广泛应用。

什么是函数柯里化
函数柯里化指的是将一个接收多个参数的函数,转换成一系列接收一个单一参数(或部分参数)的函数的技术,当传入的参数数量达到原函数的参数要求时,才会执行最终的计算逻辑。它的核心特点是参数复用和延迟执行。
基础柯里化实现
我们可以通过高阶函数来实现一个简单的柯里化函数,示例如下:
// 基础柯里化实现
function curry(fn) {
return function curried(...args) {
// 如果当前传入的参数数量大于等于原函数的参数数量,直接执行原函数
if (args.length >= fn.length) {
return fn.apply(this, args);
}
// 否则返回一个新函数,继续接收剩余参数
return function(...nextArgs) {
return curried.apply(this, args.concat(nextArgs));
};
};
}
// 测试用的原函数,接收三个参数
function add(a, b, c) {
return a + b + c;
}
// 柯里化后的函数
const curriedAdd = curry(add);
console.log(curriedAdd(1)(2)(3)); // 输出6
console.log(curriedAdd(1, 2)(3)); // 输出6
console.log(curriedAdd(1)(2, 3)); // 输出6
柯里化的实际应用场景
柯里化最常见的场景是参数复用,比如我们需要多次调用一个函数,其中部分参数是固定的,就可以通过柯里化提前固定这些参数:
// 场景:生成不同前缀的日志信息
function log(prefix, level, message) {
console.log(`[${prefix}] ${level}: ${message}`);
}
const curriedLog = curry(log);
// 固定前缀为app
const appLog = curriedLog('app');
// 固定前缀和级别为info
const appInfoLog = appLog('info');
appInfoLog('用户登录成功'); // 输出[app] info: 用户登录成功
appInfoLog('数据加载完成'); // 输出[app] info: 数据加载完成
什么是函数组合
函数组合指的是将多个函数组合成一个新函数,新函数的执行逻辑是依次调用组合的函数,前一个函数的输出作为后一个函数的输入,最终返回最后一个函数的执行结果。它可以把细粒度的函数拼接成复杂的处理逻辑,避免嵌套调用带来的可读性问题。
基础函数组合实现
函数组合的实现思路是从右到左依次执行函数,示例如下:
// 基础函数组合实现,从右到左执行
function compose(...fns) {
return function(x) {
return fns.reduceRight((acc, fn) => fn(acc), x);
};
}
// 定义几个简单的处理函数
function double(x) {
return x * 2;
}
function addOne(x) {
return x + 1;
}
function square(x) {
return x * x;
}
// 组合函数:先平方,再加1,再乘2
const process = compose(double, addOne, square);
console.log(process(3)); // 先3*3=9,再9+1=10,再10*2=20,输出20
如果需要从左到右执行函数组合,也可以使用pipe函数,实现方式和compose类似,只是把reduceRight换成reduce即可:
// 从左到右执行的函数组合
function pipe(...fns) {
return function(x) {
return fns.reduce((acc, fn) => fn(acc), x);
};
}
// 从左到右组合:先乘2,再加1,再平方
const processPipe = pipe(double, addOne, square);
console.log(processPipe(3)); // 3*2=6,6+1=7,7*7=49,输出49
柯里化与组合的结合使用
柯里化和组合经常搭配使用,柯里化可以把函数转换成更容易组合的形式,组合则可以把这些小函数拼接成完整的逻辑。比如我们可以把之前的处理函数都柯里化,再组合使用:
// 柯里化后的处理函数 const curriedDouble = curry(double); const curriedAddOne = curry(addOne); const curriedSquare = curry(square); // 组合柯里化后的函数 const combinedProcess = pipe(curriedDouble, curriedAddOne, curriedSquare); console.log(combinedProcess(2)); // 2*2=4,4+1=5,5*5=25,输出25 // 也可以先固定部分参数再组合 const doubleThenAddFixed = pipe(curriedDouble, curriedAddOne(5)); console.log(doubleThenAddFixed(3)); // 3*2=6,6+5=11,输出11
注意事项
- 柯里化函数的参数长度依赖原函数的
length属性,如果原函数使用了默认参数或者剩余参数,可能会导致length不符合预期,需要额外处理。 - 函数组合中的每个函数最好都是纯函数,避免副作用,这样才能保证组合后的逻辑可预测,方便调试。
- 如果组合的函数过多,建议给每个步骤添加清晰的注释,或者拆分成更小的组合单元,避免逻辑过于复杂。
JavaScript函数柯里化函数组合高阶函数函数式编程修改时间:2026-07-13 22:39:32