闭包实现带过期清理的本地缓存代理:封装Map存储{value, expiresAt},暴露get/set/clear接口;get自动惰性清理过期项,支持手动clear或按需批量清理;默认TTL可配置,键值类型需一致,单线程下安全。

用闭包实现一个带过期清理的本地缓存代理,核心是:封装缓存数据 + 时间戳 + 定期/按需检查过期。不需要依赖外部库,纯 JS 即可完成。
缓存结构设计:键值对 + 过期时间
每个缓存项存储为对象:{ value, expiresAt },其中 expiresAt 是毫秒时间戳(如 Date.now() + 60 * 1000 表示 60 秒后过期)。缓存容器本身用普通对象({})或 Map 都可以,闭包确保它不被外部直接修改。
闭包封装缓存逻辑,暴露 get/set/clear 接口
把缓存对象、读写方法都包裹在立即执行函数中,只返回干净的 API:
const createCache = (defaultTTL = 5 * 60 * 1000) => {
const store = new Map(); // 用 Map 更适合键为非字符串类型
<p>const isExpired = (item) => Date.now() > item.expiresAt;</p><p><span>立即学习</span>“<a href="https://pan.quark.cn/s/c1c2c2ed740f" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">Java免费学习笔记(深入)</a></a>”;</p><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/xiazai/skill7377" title="Java Maven Secondary Analysis"><img
src="https://img.php.cn/upload/skill/000/000/081/179144831942131.jpg" alt="Java Maven Secondary Analysis" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/xiazai/skill7377" title="Java Maven Secondary Analysis">Java Maven Secondary Analysis</a>
<p>分析ZIP压缩包或GitLab仓库中的Java Maven项目,确定二次开发范围、类数量、模块分布及生产相关指标。</p>
</div>
<a href="/xiazai/skill7377" title="Java Maven Secondary Analysis" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div><p>const get = (key) => {
const item = store.get(key);
if (!item || isExpired(item)) {
store.delete(key);
return undefined;
}
return item.value;
};</p><p>const set = (key, value, ttl = defaultTTL) => {
store.set(key, {
value,
expiresAt: Date.now() + ttl
});
};</p><p>const clear = () => store.clear();</p><p>return { get, set, clear };
};</p><p>// 使用示例
const cache = createCache(10000); // 默认 10 秒过期
cache.set('user:123', { name: 'Alice' }, 30000); // 显式设 30 秒
console.log(cache.get('user:123')); // 第一次取值正常
setTimeout(() => {
console.log(cache.get('user:123')); // 30 秒后为 undefined
}, 35000);
可选增强:自动惰性清理 + 手动清理过期项
上面的 get 已在读取时清理单个过期项(惰性清理),但若长期只写不读,过期项会堆积。可加一个轻量级清理方法:
-
手动触发全量清理:遍历
store,删除所有过期项 -
定时自动清理(谨慎使用):用
setInterval每分钟扫一次,避免高频影响性能 -
写入时顺带清理少量过期项:比如每次
set前随机删 1~3 个过期项,平衡开销与内存占用
注意事项和边界处理
实际使用中要注意几点:
-
key 类型要一致:Map 对
{a:1}和{a:1}视为不同 key;若需对象/数组作 key,先 JSON 序列化(注意循环引用) - value 不能是函数或 DOM 节点等不可序列化对象(除非你明确知道它们不会被持久化或跨环境传递)
-
默认 TTL 设为 0 表示永不过期,此时
isExpired可跳过判断 - 并发写入无需加锁,JS 单线程模型下天然安全;但若未来扩展到 Worker 环境,需考虑 SharedArrayBuffer 或 MessageChannel 同步
这个方案简洁、可控、无副作用,适合中小型前端项目做请求结果缓存、表单草稿暂存、配置预加载等场景。

















