柯里化本身不实现缓存,但通过闭包固化部分参数,为 memoize 提供稳定输入键,从而提升缓存命中率与可控性;典型用法是先柯里化生成专用函数,再对其单参数形式做缓存。

JavaScript 中柯里化本身不直接实现缓存,但它能和缓存逻辑自然结合——关键在于用闭包保存已传参数(用于后续复用),再把缓存结构嵌套进去。真正起缓存作用的是独立的 memoize 机制,柯里化负责把“函数 + 部分参数”固化成可复用的新函数,让缓存更精准、更可控。
缓存函数需要柯里化来做什么
缓存的核心是“相同输入 → 直接返回上次结果”,但很多函数的输入不是简单值(比如对象、数组),或者你只想对某几个固定参数做缓存。这时靠柯里化预设一部分参数,就能把多变输入压缩为稳定键(key):
- 避免缓存键冲突:比如
get(url, options)中options是对象,每次新建对象都会导致缓存失效;柯里化后变成getWithHost('https://api.com')(url),缓存只看url字符串即可 - 分离配置与数据:API 请求常需 host/token/timeout 等公共配置,柯里化提前绑定,缓存只关注业务参数(如用户 ID、页码)
- 提升缓存命中率:固定部分参数后,剩余参数组合更少、更规律,缓存更容易复用
柯里化 + 缓存的典型组合写法
不是把柯里化函数直接丢给 memoize,而是先柯里化生成专用函数,再对其做缓存:
function request(method, url, data) {
return fetch(`${method} ${url}`, { body: JSON.stringify(data) });
}
// 第一步:柯里化,固定 method 和基础配置
const get = curry(request)('GET');
const post = curry(request)('POST');
// 第二步:对具体业务函数缓存(只缓存 url 这个稳定参数)
const getCachedUser = memoize((url) => get(url)({ id: 123 }));
getCachedUser('/api/user'); // 发请求并缓存
getCachedUser('/api/user'); // 直接返回缓存结果
这里 memoize 只接收单参数函数,而柯里化确保了 get(url) 是纯函数、无副作用、输入确定输出,适合缓存。
立即学习“Java免费学习笔记(深入)”;
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
一个带缓存能力的柯里化增强版
如果想让柯里化函数自带缓存能力(比如固定前几个参数后,对后续调用自动缓存),可以这样扩展:
function curryWithCache(fn) {
const cache = new Map();
return function curried(...args) {
if (args.length >= fn.length) {
const key = JSON.stringify(args);
if (cache.has(key)) return cache.get(key);
const result = fn(...args);
cache.set(key, result);
return result;
} else {
return (...moreArgs) => curried(...args, ...moreArgs);
}
};
}
注意点:
- 缓存键用
JSON.stringify(args)简单处理,仅适用于参数都是基础类型或可序列化对象 - 实际项目中建议用更健壮的 key 生成器(如 lodash 的
lodash.memoize支持自定义 resolver) - 这种写法适合参数少、组合有限的场景;高频或大数据量场景,仍推荐分开使用 curry + memoize,职责更清晰
为什么不能直接缓存原始多参函数
直接对 add(a, b, c) 做缓存,每次调用都要把三个参数拼成 key。但如果经常用 add(10, b, c),你就得反复传 10 ——既冗余,又容易因参数顺序错乱导致缓存未命中。柯里化后:
-
add10 = curry(add)(10)→ 得到新函数 -
memoizedAdd10 = memoize(add10)→ 缓存只看后两个参数 - 调用
memoizedAdd10(5, 3)和memoizedAdd10(5, 3)能稳定命中
本质上,柯里化帮你把“变化维度”做了分层,缓存就可以按需作用在最合适的那一层上。

















