柯里化通过闭包固定前置参数实现“参数缓存”,而非结果缓存;memoize负责缓存函数执行结果,二者职责分离但可组合:先柯里化预设参数,再对最终单参函数应用memoize,从而兼顾参数复用与计算结果复用。

柯里化本身不直接缓存计算结果,它通过闭包“缓存参数”,为后续调用提供固定前置值;真正缓存函数执行结果的,是 memoize 这类单独的缓存机制。两者常配合使用,但职责分明:闭包记的是“参数”,memoize 存的是“返回值”。
闭包如何在柯里化中“缓存参数”
柯里化函数每次接收一部分参数后,返回一个新函数。这个新函数内部通过闭包捕获已传入的参数,并在后续调用中复用它们。
- 例如:
const addCurried = a => b => a + b,调用addCurried(5)返回b => 5 + b,其中a = 5就被闭包保留在内存中 - 只要返回的函数还存在(比如赋值给变量
add5),5就不会被垃圾回收,相当于“参数缓存” - 这种缓存是自动发生的,无需手动管理,本质是 JavaScript 作用域链和闭包机制的自然体现
为什么不能靠柯里化缓存“计算结果”
柯里化生成的中间函数(如 add5)每次调用都会重新执行运算逻辑,不会记住上次 add5(3) 算出的 8:
-
add5(3)→ 执行5 + 3→ 得到8 -
add5(3)再调一次 → 还是执行5 + 3→ 再得8,但没跳过计算 - 除非你额外加一层 memoize,否则相同输入仍会重复计算
怎么组合柯里化与结果缓存
先柯里化预设参数,再对最终单参函数做 memoize,才能既省参数又省计算:
立即学习“Java免费学习笔记(深入)”;
- 定义原始函数:
const heavy = (a, b, c) => { /* 耗时运算 */ return a * b + c; } - 柯里化固定前两个参数:
const heavyFixed = curry(heavy)(2)(3)→ 得到c => 2 * 3 + c - 再缓存结果:
const cachedHeavy = memoize(heavyFixed) - 之后调用
cachedHeavy(4)、cachedHeavy(4)第二次就直接返回缓存值,不再执行表达式
实际写法建议
不要手写复杂柯里化逻辑,优先使用成熟工具:
- Lodash:
const idFormatter = _.curry(format)('【ID】', '') - Ramda:
const postJson = R.curry(request)('POST')(null)({ 'Content-Type': 'application/json' }) - 搭配 memoize:
import { memoize } from 'lodash'; const cached = memoize(curriedFn(2))


















