You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript:以编程方式添加和删除智能 getter

实现仅首次计算的缓存Getter

嘿,刚好可以用你提到的那种“智能getter”思路来实现,核心就是第一次访问时计算值,然后把这个getter属性替换成普通的缓存值,后续访问就直接读缓存啦。我给你拆解下具体实现:

核心思路

第一次触发getter时,执行计算逻辑得到结果,然后删除当前的getter属性(所以必须让属性可配置),再把计算结果直接赋值给该属性。这样后续访问这个属性时,就会直接读取缓存的普通值,不会再触发getter计算了。

具体代码示例

封装成复用函数(推荐)

如果需要给多个对象/属性添加缓存getter,可以封装成工具函数:

function addCachedGetter(obj, propName, computeValue) {
  Object.defineProperty(obj, propName, {
    get() {
      // 执行耗时/一次性计算
      const result = computeValue();
      // 删除当前的getter属性(必须先设置configurable: true才能删)
      delete this[propName];
      // 将计算结果赋值为普通属性,后续直接读取
      this[propName] = result;
      return result;
    },
    // 关键:必须开启可配置,否则无法删除getter属性
    configurable: true,
    // 可选:如果需要枚举该属性,加上enumerable: true
    enumerable: true
  });
}

// 用法示例
const myObj = {};
// 传入计算逻辑,比如模拟一个耗时操作
addCachedGetter(myObj, 'text', () => {
  console.log('正在计算text的值...'); // 只会打印一次
  return '这是缓存后的文本内容';
});

console.log(myObj.text); // 输出:正在计算text的值... 这是缓存后的文本内容
console.log(myObj.text); // 直接输出:这是缓存后的文本内容(不再计算)

单个属性直接定义

如果只是给单个属性加缓存getter,直接写也很简单:

const obj = {};
Object.defineProperty(obj, 'text', {
  get() {
    // 这里写你的计算逻辑,比如从DOM获取数据、复杂计算等
    const cachedText = '首次计算得到的结果';
    console.log('首次计算中...');
    // 删除当前getter
    delete this.text;
    // 赋值为普通属性
    this.text = cachedText;
    return cachedText;
  },
  configurable: true
});

关键注意点

  • 一定要设置configurable: true:默认用Object.defineProperty定义的属性是不可配置的,没办法删除,所以这一步是实现缓存的核心前提。
  • 后续访问性能拉满:转换成普通属性后,后续访问和读取普通对象属性完全一样,没有额外的getter调用开销。
  • 计算逻辑只会执行一次:不管你访问多少次属性,只有第一次会触发计算,完美符合你的缓存需求。

内容的提问来源于stack exchange,提问作者Johannes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:28:00