跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

如何利用闭包实现具备“参数敏感型缓存”特征的 高阶函数优化插件

参数敏感型缓存需精确区分类型、引用、undefined/null/NaN及参数顺序,推荐用Map配合自定义键生成器实现;增强策略包括支持this、LRU容量控制、手动清理及纯函数校验。 用闭包实现“参数敏感型缓存”的高阶函数,核心在于:让缓存键能精确区分不同参数组合,避免因参数序列化失真导致的误命中或漏命中。这不是简单存个对象,而是围绕参数的结构、类型、顺序和语义做精准建模。 参数敏感型缓存的关键设计点 所谓“参数敏感”,是指缓存机制必须能识别以下差异: 值相同但类型不同 :比如
1
和
"1"
应视为两个键 对象内容相同但引用不同 :
{a: 1}
和
{a: 1}
默认不是同一键(除非显式深比较) undefined / null / NaN 的明确表达 :JSON.stringify 会忽略
undefined
,导致
[1, undefined]
和
[1]
生成相同 key 参数顺序不可互换 :
fn('a', 'b')
和
fn('b', 'a')
必须对应不同结果 用 Map + 自定义键生成器实现健壮缓存 推荐弃用
JSON.stringify
,改用
Map
存储,并编写轻量级键生成函数,保留原始类型信息: // 支持多参数、类型区分、undefined 显式编码
function memoize(fn) {
const cache = new Map();
return function(...args) {
// 生成唯一可比键:[type, value] 元组数组
const key = args.map(arg => [
typeof arg,
arg === undefined ? 'UNDEFINED' :
arg === null ? 'NULL' :
arg === NaN ? 'NaN' :
arg
]);
if (cache.has(key)) {
return cache.get(key);
}
const result = fn.apply(this, args);
cache.set(key, result);
return result;
};
}
适配实际场景的增强策略 生产环境需考虑更多边界: 支持 this 上下文 :用
fn.call(this, ...args)
替代
apply
,确保原函数行为一致 限制缓存容量 :加入 LRU 逻辑,或直接使用
lru-cache
库替代原生 Map 允许手动清理 :返回的函数挂载
.clear()
方法,便于测试或重置状态 标记纯函数前提 :在文档或运行时校验输入是否为纯函数(无副作用、无外部依赖),否则抛警告 一个即插即用的优化插件雏形 封装成可配置的高阶函数工厂,支持常见定制项:
function createMemoPlugin({ maxAge = 0, maxSize = 100, keyGen } = {}) {
return function memoize(fn) {
const cache = new Map();
const getKey = keyGen || defaultKeyGen;
return function(...args) {
const key = getKey(args);
const entry = cache.get(key);
if (entry && (!maxAge || Date.now() - entry.time < maxAge)) {
return entry.value;
}
const value = fn.call(this, ...args);
cache.set(key, { value, time: Date.now() });
if (cache.size > maxSize) cache.delete(cache.keys().next().value);
return value;
};
};
}
这样就能按需生成插件实例:
const fastMath = createMemoPlugin({ maxSize: 50 });
const memoizedFib = fastMath((n) => n <= 1 ? n : memoizedFib(n-1) + memoizedFib(n-2));

相关文章