柯里化是将多参数函数转换为一系列单参数函数的过程,核心是参数分步传递和闭包记忆已传参数,支持部分应用、复用及函数组合,适用于配置预设、事件处理等场景。

柯里化是把多参数函数转换成一系列单参数函数的过程
它不是一次性传入全部参数,而是每次只传一个,返回一个接收下一个参数的新函数,直到所有参数都传完才执行原函数。核心在于“参数分步传递”和“闭包记忆已传参数”。比如 add(1)(2)(3) 等价于 add(1, 2, 3),但前者更灵活,支持部分应用和复用。
手动实现一个通用柯里化函数
关键思路是:获取目标函数的期望参数个数(fn.length),用闭包保存已传参数,递归返回新函数,直到参数足够就调用原函数。
示例代码:
function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn.apply(this, args);
} else {
return function(...nextArgs) {
return curried.apply(this, args.concat(nextArgs));
};
}
};
}
- 支持任意函数,如 const add = (a, b, c) => a + b + c; → const curriedAdd = curry(add);
- 可链式调用:curriedAdd(1)(2)(3) 或 curriedAdd(1, 2)(3) 或 curriedAdd(1)(2, 3) 都能正确计算
- 注意:fn.length 只反映形参个数,不处理 rest 参数(...args);若需支持,需额外判断或改用显式参数数量传入
用柯里化提升复用性的典型场景
它让函数更专注、更易组合,尤其适合配置预设、事件处理、工具函数封装等场景。
立即学习“Java免费学习笔记(深入)”;
-
预设通用配置:比如封装带默认前缀的 HTTP 请求函数
const request = curry((baseUrl, method, path) => fetch(`${baseUrl}/${path}`, {method}));
const githubApi = request('https://api.github.com');
后续直接用 githubApi('GET', '/users'),无需重复写 baseUrl -
事件处理器复用:如统一日志埋点
const logClick = curry((action, element) => console.log(`Clicked ${action} on`, element));
button.addEventListener('click', logClick('submit')); -
与函数式工具链配合:结合 map、filter 时避免写匿名函数
[1, 2, 3].map(curry(Math.pow)(2)) → [1, 4, 9](计算平方)
注意事项和实用建议
柯里化不是银弹,用对地方才真正提效。











