柯里化是将多参函数转为单参函数链的转换技术,核心是递归收集参数直至满足原函数形参个数后执行;典型场景包括预设配置、事件复用、工具函数组合及日志增强;需注意参数顺序、函数类型及性能开销。

函数柯里化(Currying)是指将一个接收多个参数的函数,转换为一系列只接收一个参数的函数链。每次调用返回一个新的函数,直到所有参数都传入后才执行原逻辑。
怎么实现一个通用柯里化函数?
核心思路是:保存已传参数,递归等待剩余参数,当参数数量满足原函数要求时触发执行。
简单手写示例:
function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn.apply(this, args);
} else {
return function(...moreArgs) {
return curried.apply(this, args.concat(moreArgs));
};
}
};
}
// 使用示例
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
柯里化在实际开发中有哪些典型场景?
它不是炫技,而是解决具体问题的实用模式:
立即学习“Java免费学习笔记(深入)”;
- 预设配置参数:比如封装 API 请求函数,提前固定 base URL 或 headers
- 事件处理器复用:给按钮绑定点击事件时,避免内联匿名函数导致重复渲染(React 中尤其有用)
-
构建高阶工具函数:如
map、filter配合柯里化后更易组合,例如const isGreaterThan = curry((a, b) => b > a); const isPositive = isGreaterThan(0); - 日志与调试增强:对函数做柯里化包装,自动注入上下文信息(如模块名、操作类型)
柯里化和偏函数(Partial Application)有什么区别?
容易混淆但关键不同:
- 柯里化必须严格逐个传参,每次只接受一个,且返回新函数;即使一次传多个,也仅用于“提前填充”,后续仍需继续调用
- 偏函数是一次性填入部分参数,返回一个参数更少的新函数,不要求单参数调用,也不强制分步
- 简单记:柯里化是“强制拆成一元函数链”,偏函数是“减少参数个数”
使用时要注意什么?
柯里化虽灵活,但别滥用:
- 参数顺序很重要——把最可能变化的参数放在最后,便于前置固化
- 箭头函数无法通过
arguments获取长度,用fn.length判断时需确保原函数是普通函数声明/表达式 - 在性能敏感或循环频繁调用的场景中,避免无意义柯里化,防止闭包堆积和额外函数创建开销
- TypeScript 中需注意类型推导,复杂柯里化可能需要手动声明泛型或重载











