柯里化通过闭包和箭头函数将多参数函数转为单参数链式调用,固定参数可用嵌套箭头函数(如add=a=>b=>c=>a+b+c),灵活版则累积参数并比对fn.length;需注意this绑定、默认参数影响length及重复调用风险。

函数表达式实现柯里化,关键在于用简洁、可复用的方式把多参数函数转成单参数链式调用。它不依赖类或复杂状态,靠闭包和箭头函数就能写出清晰、轻量的版本。
用箭头函数一层层嵌套
这是最直观的写法,适合参数数量固定、逻辑简单的场景:
- 每个参数对应一个箭头函数,返回下一个函数,最后执行计算
- 例如:const add = a => b => c => a + b + c;
- 调用 add(1)(2)(3) 直接得 6,无需额外 curry 工具
- 优点是代码极简、无副作用;缺点是无法支持 add(1, 2)(3) 这类多参混用
结合 rest 参数与闭包累积参数
想兼顾灵活性(一次传多个、分多次传),就得让函数能“记住”已传参数:
- 用数组缓存所有传入参数,每次调用都追加
- 判断累积长度是否达到原函数形参个数(fn.length)
- 未满则返回自身;满足则用 fn(...args) 执行
- 示例:const curry = fn => (...args) => args.length >= fn.length ? fn(...args) : (...more) => curry(fn)(...args, ...more);
避免常见陷阱
用函数表达式写柯里化时,容易忽略几个细节:
- this 绑定问题:箭头函数不绑定 this,若原函数依赖上下文,需显式用 fn.call(this, ...args)
- 默认参数干扰:fn.length 不统计带默认值的参数,比如 (a, b = 1, c) => {} 的 length 是 1,不是 3
- 重复调用风险:不要在返回函数中直接执行原函数,除非确认参数已齐备,否则可能提前触发副作用
配合高阶函数提升实用性
纯函数表达式本身不带业务逻辑,但可以快速生成定制函数:
- 比如日志封装:const log = level => time => msg => console.log(`[${level}] ${time}: ${msg}`);
- 再派生:const errorLog = log('ERROR')(new Date().toISOString());
- 这样写的函数天然支持组合、测试、复用,也便于单元隔离











