柯里化是将多参函数拆为单参函数链的参数传递方式转换,不改变逻辑只改变调用节奏;关键在分步传参、延迟执行,需闭包缓存参数并谨慎处理 length 失效问题。

柯里化不是语法糖,也不是必须用的高级技巧——它本质是把一个接收多个参数的函数,拆成一系列只接收一个参数的函数链。关键在于:它不改变原函数逻辑,只改变调用方式和参数传递节奏。
什么是 curry?它和普通函数调用的区别在哪
比如原函数是 add(a, b, c),柯里化后变成 add(a)(b)(c) 或 add(a)(b, c)(取决于实现策略)。这不是重写函数,而是包装——返回新函数,每次接收部分参数,直到参数够了才真正执行。
- 普通调用:必须一次性给全参数,缺一不可,否则
undefined参与运算 - 柯里化调用:允许分步传参,中间返回的都是函数,只有最后一步才求值
- 典型误用:把
curry当作“自动补全参数”工具——它不猜参数,也不默认填充,只是延迟执行
手写一个基础 curry 函数要注意什么
最简实现要解决两个核心问题:记下已传参数、判断是否达到原函数所需参数个数。不能简单用 length 判断——箭头函数、有默认值的参数、rest 参数都会让 fn.length 失效。
- 推荐用闭包缓存已传参数数组,用
arguments或展开收集每次调用的参数 - 执行时机:当累计参数数量 ≥ 原函数显式声明的形参数量(
fn.length)时触发,但需注意:若原函数含...args,length为前面固定参数个数,不是总参数上限 - 常见坑:
curry(add)(1)(2)(3)能运行,但curry(add)(1, 2)(3)若没处理多参合并,会出错——得在每次调用时把新参数追加进缓存数组
lodash.curry 和手写版行为差异在哪
lodash.curry 默认使用 arity(即 fn.length)作为“最小触发阈值”,但支持手动指定 arity。更重要的是:它允许一次传多个参数,内部自动合并;而多数手写版只假设单参数调用。
立即学习“Java免费学习笔记(深入)”;
- 例如
curry(Math.pow)(2, 3)在 Lodash 中直接返回8;手写若没处理多参,可能返回函数而非结果 - Lodash 还提供
curryRight和curry.placeholder,用于占位符替换(如curry(add)(_, 2)(1)→3),原生手写几乎不处理这类场景 - 性能上:Lodash 的 curry 是经过优化的,避免频繁创建闭包;简单手写版在深度柯里化(如 10 层嵌套)时可能有明显开销
柯里化真正的价值不在“看起来酷”,而在组合与复用:比如 map(curry(filter)(predicate)) 或构建配置化工具函数。但别为了柯里化而柯里化——如果函数本身参数固定且调用路径明确,直接调用更直白。最容易被忽略的一点是:柯里化后的函数无法被 instanceof 或 typeof 精准识别为原函数类型,调试时堆栈里看到的都是包装函数。









