JavaScript可通过柯里化+闭包+缓存实现带记忆功能的计算函数:先用curry将多参函数转为单参链式调用,再在闭包中维护Map缓存,以JSON.stringify(args)为key存储结果,仅对参数齐全的最终调用缓存,确保纯函数下重复调用直接返回结果。

JavaScript 中可以通过柯里化 + 闭包 + 缓存对象,实现一个带记忆功能的计算函数。核心是让每次柯里化后的函数调用都检查缓存,命中则直接返回,未命中则计算并存入缓存。
柯里化基础结构:接收参数、延迟执行
柯里化把多参数函数拆成一系列单参数函数。关键在于保留已有参数,并在最终参数齐全时执行原逻辑:
function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn(...args);
} else {
return (...moreArgs) => curried(...args, ...moreArgs);
}
};
}
加入记忆缓存:用闭包维护 cache 对象
在柯里化函数内部创建一个私有 cache,键为参数的字符串化表示(如 JSON.stringify),值为计算结果。注意:仅适用于参数可序列化的纯函数。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 使用 JSON.stringify(args) 作为缓存 key(简单场景下够用;若含函数、undefined、Symbol 等需更健壮的序列化)
- 缓存对象定义在 curried 函数外层,保证所有调用共享同一 cache
- 只对“参数个数满足要求”的最终调用做缓存,中间柯里化步骤不触发计算
完整示例:带缓存的加法柯里化函数
下面是一个三参数加法函数的柯里化 + 记忆实现:
立即学习“Java免费学习笔记(深入)”;
function add(a, b, c) {
console.log('计算中:', a, b, c); // 用于验证是否缓存生效
return a + b + c;
}
function curryWithCache(fn) {
const cache = new Map();
return function curried(...args) {
const key = JSON.stringify(args);
if (args.length >= fn.length) {
if (cache.has(key)) {
return cache.get(key);
}
const result = fn(...args);
cache.set(key, result);
return result;
} else {
return (...moreArgs) => curried(...args, ...moreArgs);
}
};
}
const cachedAdd = curryWithCache(add);
console.log(cachedAdd(1)(2)(3)); // 输出: 计算中: 1 2 3 → 6
console.log(cachedAdd(1)(2)(3)); // 输出: 6(无 log,命中缓存)
注意事项与优化建议
实际使用中需注意几个边界问题:
-
参数不可序列化:JSON.stringify 会忽略 undefined、函数、Symbol、循环引用。生产环境建议用第三方库如
fast-deep-equal或自定义 key 生成器 -
缓存大小控制:长期运行可能内存泄漏,可加 LRU 机制(例如用
lru-cache库或手动维护有序 Map) - 副作用函数不适用:缓存假设函数是纯的(相同输入总得相同输出)。若函数依赖外部状态或修改全局变量,缓存会导致行为异常
- 柯里化深度固定:上述实现依赖 fn.length,若函数使用 rest 参数或动态参数,需改用显式参数数量声明或更灵活的 API

















