当前位置:首页 > JavaScript

js实现lru

2026-02-01 08:12:32JavaScript

LRU缓存算法的实现

LRU(Least Recently Used)是一种缓存淘汰策略,当缓存空间不足时,会优先淘汰最近最少使用的数据。以下是使用JavaScript实现LRU缓存的几种方法:

使用Map实现LRU

Map对象保存键值对,并且能记住键的原始插入顺序,这使得它非常适合实现LRU缓存。

class LRUCache {
  constructor(capacity) {
    this.capacity = capacity;
    this.cache = new Map();
  }

  get(key) {
    if (!this.cache.has(key)) return -1;

    const value = this.cache.get(key);
    this.cache.delete(key);
    this.cache.set(key, value);
    return value;
  }

  put(key, value) {
    if (this.cache.has(key)) {
      this.cache.delete(key);
    }

    this.cache.set(key, value);

    if (this.cache.size > this.capacity) {
      const oldestKey = this.cache.keys().next().value;
      this.cache.delete(oldestKey);
    }
  }
}

使用双向链表和哈希表实现

这种方法结合了双向链表的高效删除/插入和哈希表的快速查找特性。

class Node {
  constructor(key, value) {
    this.key = key;
    this.value = value;
    this.prev = null;
    this.next = null;
  }
}

class LRUCache {
  constructor(capacity) {
    this.capacity = capacity;
    this.size = 0;
    this.cache = {};
    this.head = new Node(0, 0);
    this.tail = new Node(0, 0);
    this.head.next = this.tail;
    this.tail.prev = this.head;
  }

  _addNode(node) {
    node.prev = this.head;
    node.next = this.head.next;
    this.head.next.prev = node;
    this.head.next = node;
  }

  _removeNode(node) {
    const prev = node.prev;
    const next = node.next;
    prev.next = next;
    next.prev = prev;
  }

  _moveToHead(node) {
    this._removeNode(node);
    this._addNode(node);
  }

  _popTail() {
    const res = this.tail.prev;
    this._removeNode(res);
    return res;
  }

  get(key) {
    const node = this.cache[key];
    if (!node) return -1;
    this._moveToHead(node);
    return node.value;
  }

  put(key, value) {
    const node = this.cache[key];
    if (!node) {
      const newNode = new Node(key, value);
      this.cache[key] = newNode;
      this._addNode(newNode);
      this.size++;

      if (this.size > this.capacity) {
        const tail = this._popTail();
        delete this.cache[tail.key];
        this.size--;
      }
    } else {
      node.value = value;
      this._moveToHead(node);
    }
  }
}

使用ES6 Proxy实现

Proxy可以拦截对象的操作,可以用来实现LRU的自动管理。

js实现lru

function createLRUCache(capacity) {
  const cache = new Map();

  return new Proxy({}, {
    get(target, prop) {
      if (cache.has(prop)) {
        const value = cache.get(prop);
        cache.delete(prop);
        cache.set(prop, value);
        return value;
      }
      return undefined;
    },
    set(target, prop, value) {
      if (cache.has(prop)) {
        cache.delete(prop);
      }
      cache.set(prop, value);

      if (cache.size > capacity) {
        const oldestKey = cache.keys().next().value;
        cache.delete(oldestKey);
      }
      return true;
    }
  });
}

性能比较

  1. Map实现简单,但删除操作需要遍历
  2. 双向链表实现性能最优,但代码复杂度高
  3. Proxy实现最简洁,但可能在某些环境下有兼容性问题

选择哪种实现方式取决于具体应用场景和性能要求。对于大多数应用场景,Map实现已经足够高效且易于维护。

标签: jslru
分享给朋友:

相关文章

js实现点击显示和隐藏

js实现点击显示和隐藏

实现点击显示和隐藏的JavaScript方法 使用classList.toggle切换类名 通过添加/移除CSS类控制元素的显示与隐藏,需提前在CSS中定义隐藏样式(如display: none)。…

js实现驼峰

js实现驼峰

实现驼峰命名的几种方法 使用正则表达式和字符串替换 通过正则表达式匹配字符串中的特定模式(如下划线或短横线),并将其后的字母转换为大写,同时移除分隔符。 function toCamelCase(s…

js实现吸色

js实现吸色

使用Canvas实现吸色功能 通过Canvas的getImageData方法获取像素颜色数据。创建一个Canvas元素,将目标图像绘制到Canvas上,通过鼠标事件获取坐标对应的颜色值。 c…

js实现滚动

js实现滚动

实现滚动效果的方法 在JavaScript中实现滚动效果可以通过多种方式完成,以下是一些常见的方法: 使用window.scrollTo() window.scrollTo()方法可以将页面滚动到指…

js验证码的实现

js验证码的实现

验证码的基本实现原理 验证码(CAPTCHA)的核心目标是区分人类用户和自动化程序。JavaScript可用于生成或验证客户端验证码,但需注意纯前端验证可能被绕过,通常需结合后端验证。 纯前端验证码…

js实现 拖动

js实现 拖动

实现拖动的步骤 HTML 结构 创建一个可拖动的元素和一个放置区域: <div id="draggable" draggable="true">拖动我</div> <d…