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
相关产品推荐
相关产品推荐

