柯里化是将多参函数转为单参函数链的过程,通过闭包累积参数、延迟求值,核心为固定参数+返回函数链;示例curry函数基于fn.length判断参数是否齐备,支持多种调用方式。

柯里化(Currying)是将一个接收多个参数的函数,转换为一系列只接收一个参数的函数的过程。每次调用返回一个新的函数,直到收集齐所有参数,才真正执行原函数。
柯里化的核心特点
它不是简单地“分次传参”,而是通过闭包保存已传入的参数,逐步累积,最终触发计算。关键在于:固定部分参数 + 延迟求值 + 返回函数链。
手动实现一个基础柯里化函数
下面是一个通用、可复用的 curry 工具函数:
立即学习“Java免费学习笔记(深入)”;
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));
};
}
};
}说明:
- fn.length 获取原函数期望的形参个数,作为“收参完成”的判断依据
- 每次调用 curried 时,先检查当前参数是否足够;够了就执行,不够就返回新函数继续等
- 使用 apply 保证 this 上下文和参数数组正确传递
实际例子:加法函数柯里化
原始函数:
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
三种写法都有效,因为内部做了参数合并逻辑。
进阶注意点
真实项目中需考虑更多边界情况:
- 支持 显式指定参数个数(如 curry(fn, 3)),避免依赖 fn.length(箭头函数、无名函数或含默认参数时 length 不可靠)
- 处理 arguments 对象或类数组,必要时用 Array.from 转换
- 若需保留原函数的属性(如 name、length),可用 Object.assign 或 defineProperty 拷贝
- 某些场景下希望支持“占位符”(如 _),类似 Lodash 的 curry,需额外解析参数中的占位标识
不复杂但容易忽略











