map比object更适合实现lru缓存,因其迭代顺序严格按插入序、支持o(1)增删查、set自动置尾、可高效删除首项;而object无法直接删除最久未用项且需手动维护顺序。

JavaScript中用Map实现LRU缓存非常自然——因为Map的迭代顺序严格遵循插入顺序,且支持O(1)的增删查操作,天然适配LRU“最近最少使用”的核心逻辑:把最新访问的项移到末尾,淘汰开头的旧项。
为什么Map比Object更适合LRU
Object的属性遍历顺序虽在ES2015后也保证插入序,但不支持按需删除首项(即“最久未用”项);而Map提供keys()、values()、entries()等可迭代接口,配合iterator.next().value能快速获取首个键,删除效率稳定。更重要的是,Map的set(key, value)会自动将该键值对移到末尾,省去手动维护顺序的开销。
LRU缓存的核心操作逻辑
每次get或put都触发“访问即更新位置”行为:
-
get(key):若存在,先
delete再set,使其成为最新项;返回对应值;否则返回undefined -
put(key, value):先
set(自动置尾);若超出容量,调用delete(map.keys().next().value)移除头项
一个简洁可靠的实现示例
以下代码封装为类,支持初始化容量限制,并兼顾边界处理:
class LRUCache {
constructor(capacity) {
this.capacity = capacity;
this.cache = new Map();
}
get(key) {
if (!this.cache.has(key)) return -1;
const val = this.cache.get(key);
this.cache.delete(key);
this.cache.set(key, val);
return val;
}
put(key, value) {
if (this.cache.has(key)) {
this.cache.delete(key);
}
this.cache.set(key, value);
if (this.cache.size > this.capacity) {
const firstKey = this.cache.keys().next().value;
this.cache.delete(firstKey);
}
}
}
使用时只需:const cache = new LRUCache(2); cache.put(1,1); cache.put(2,2); cache.get(1); cache.put(3,3); —— 此时key=2被自动淘汰。
注意事项与优化点
实际项目中可考虑:
- 在
get中避免重复读取值(如上例先get再delete+set,可改用const val = this.cache.get(key); this.cache.delete(key); this.cache.set(key, val);保持语义清晰) - 若需频繁获取缓存大小或判断是否为空,直接用
this.cache.size,无需额外维护计数器 - 不建议在构造函数中预设默认值(如
new Map([['dummy', 0]])),会干扰LRU顺序逻辑
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











