坏蛋格鲁坏蛋格鲁

【Function】JS 封装 LocalStorage 操作函数


/**
 * LocalStorageHelper – 浏览器本地存储的轻量级封装
 * 提供增删改查、过期策略、批量操作、JSON 序列化、命名空间隔离等常用能力。
 * 所有数据默认以 JSON 格式存储;支持设置过期时间并在读取时自动清理。
 */
class LocalStorageHelper {
  /**
   * 构造函数
   * @param {Object} [options={}] 全局配置
   * @param {string} [options.prefix=''] 键名前缀,避免多个项目冲突
   * @param {number} [options.ttl=0] 默认存活毫秒数,0 表示不过期
   */
  constructor(options = {}) {
    const { prefix = '', ttl = 0 } = options;
    this.prefix = prefix;
    this.defaultTTL = ttl;
  }

  /* ---------- 私有工具方法 ---------- */

  /**
   * 生成带前缀的真实 key
   * @private
   * @param {string} key 原始键名
   * @returns {string} 带前缀的键名
   */
  _getKey(key) {
    return this.prefix + key;
  }

  /**
   * 包装数据:存储值 + 元信息(过期时间戳)
   * @private
   * @param {*} value 原始值
   * @param {number} ttl 存活时间(毫秒)
   * @returns {Object} 包装后的数据
   */
  _wrap(value, ttl) {
    return {
      value,
      exp: ttl > 0 ? Date.now() + ttl : null,
    };
  }

  /**
   * 解析并校验数据:若已过期则自动删除
   * @private
   * @param {string} raw 原始 localStorage 字符串
   * @returns {*} 有效值;若过期或解析失败则返回 undefined
   */
  _unwrap(raw) {
    try {
      const { value, exp } = JSON.parse(raw);
      if (exp && Date.now() > exp) return undefined;
      return value;
    } catch {
      return undefined;
    }
  }

  /* ---------- 公开 API ---------- */

  /**
   * 写入一条数据
   * @param {string} key 键名
   * @param {*} value 任意可 JSON 序列化的值
   * @param {number} [ttl] 存活毫秒数;不传则使用构造器默认值
   * @returns {LocalStorageHelper} 支持链式调用
   */
  set(key, value, ttl = this.defaultTTL) {
    const wrapped = this._wrap(value, ttl);
    localStorage.setItem(this._getKey(key), JSON.stringify(wrapped));
    return this;
  }

  /**
   * 读取一条数据
   * @param {string} key 键名
   * @param {*} [defaultValue=null] 不存在或已过期时的默认值
   * @returns {*} 存储值
   */
  get(key, defaultValue = null) {
    const raw = localStorage.getItem(this._getKey(key));
    if (raw === null) return defaultValue;
    const value = this._unwrap(raw);
    if (value === undefined) {
      this.remove(key); // 自动清理过期数据
      return defaultValue;
    }
    return value;
  }

  /**
   * 删除一条数据
   * @param {string} key 键名
   * @returns {LocalStorageHelper} 支持链式调用
   */
  remove(key) {
    localStorage.removeItem(this._getKey(key));
    return this;
  }

  /**
   * 批量写入数据
   * @param {Object} map 键值对对象
   * @param {number} [ttl] 统一 TTL;不传使用默认
   * @returns {LocalStorageHelper} 支持链式调用
   */
  setAll(map, ttl = this.defaultTTL) {
    Object.entries(map).forEach(([k, v]) => this.set(k, v, ttl));
    return this;
  }

  /**
   * 批量读取数据
   * @param {string[]} [keys] 需要读取的键名数组;留空则读取所有带前缀的键
   * @returns {Object} 键值对对象;不存在或已过期的键不会出现
   */
  getAll(keys) {
    const result = {};
    const list = keys || Object.keys(localStorage)
      .filter(k => k.startsWith(this.prefix))
      .map(k => k.slice(this.prefix.length));

    list.forEach(k => {
      const val = this.get(k);
      if (val !== null) result[k] = val;
    });
    return result;
  }

  /**
   * 清空当前实例命名空间下的所有数据
   * @returns {LocalStorageHelper} 支持链式调用
   */
  clear() {
    const keys = Object.keys(localStorage)
      .filter(k => k.startsWith(this.prefix));
    keys.forEach(k => localStorage.removeItem(k));
    return this;
  }

  /**
   * 获取当前命名空间下的占用空间(字节数,仅作估算)
   * @returns {number} 字节数
   */
  size() {
    const keys = Object.keys(localStorage)
      .filter(k => k.startsWith(this.prefix));
    return keys.reduce((acc, k) => acc + k.length + (localStorage[k]?.length || 0), 0);
  }
}



// Test:
const ls = new LocalStorageHelper({ prefix: 'myApp_', ttl: 1000 * 60 * 60 });
ls.set('token', 'abc123');
ls.set('user', { id: 1, name: 'Tom' }, 1000 * 60 * 5); // 5 分钟后过期
console.log(ls.size());
console.log(ls.get('user')); // { id: 1, name: 'Tom' }
ls.clear();
console.log(ls.size());
本原创文章未经允许不得转载 | 当前页面:坏蛋格鲁 » 【Function】JS 封装 LocalStorage 操作函数

评论