核心是用空间换时间:将函数输入与输出缓存,相同输入直接返回结果;用map作容器支持任意参数类型作key,避免序列化陷阱,仅缓存纯函数,并设容量限制防内存爆炸。

核心是用空间换时间:把函数某次的输入和输出记下来,下次相同输入直接返回结果,跳过重复计算。
用 Map 做缓存容器,支持任意参数类型
对象作缓存时,数组、对象、NaN 作为 key 会变成 [object Object] 或 "",导致键冲突或全部失效。Map 没这个问题,能直接用数组、对象、函数甚至 NaN 当 key。
- 多参数传入时,可直接用
args数组当 key(Map 原生支持) - 若需兼容旧环境或做更精细控制,再考虑序列化,但别盲目用
JSON.stringify
谨慎处理参数序列化
JSON.stringify 看似方便,但遇到 Date、RegExp、undefined、循环引用会出错或生成不一致的 key。
- 参数全是字符串/数字/布尔值?用
args.join('_')更快、更可控 - 含对象或嵌套结构?推荐用
fast-deep-equal库比对相等性,或自己写稳定哈希(比如按字段名排序后 stringify) - 避免对 DOM 元素、事件对象、函数做缓存——它们每次都是新引用,缓存基本无效
只缓存纯函数,否则结果不可信
缓存生效的前提是:相同输入,输出恒定。以下行为会让缓存“假”:
- 调用
Date.now()、Math.random()、performance.now() - 发起网络请求(
fetch)、读取localStorage - 修改外部变量、push 到全局数组、触发 DOM 变更
加了缓存后表面变快,实则掩盖逻辑错误。比如用户点两次按钮,第二次没发请求,界面却没更新。
必须设容量限制,防内存爆炸
Canvas 渲染、滚动监听、鼠标移动等高频场景,每秒可能调用几十上百次。无节制缓存会让 Map 越来越大,拖慢 GC、引发卡顿。
- 手动实现 LRU:缓存上限设为 100 条,每次
set前检查size,超限就删最早 entry - 直接用
lru-cache库,它已内置max、ttl、dispose回调等能力 - 对固定组合参数(如
canvas.width + scale),可设计“条件刷新”:参数变化时主动清空整个缓存
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











