寻求JavaScript类中缓存属性的简化处理方案
简化类方法缓存逻辑的方案
针对你遇到的重复缓存代码问题,这里有几个实用的简化方案,既能避免重复编写判断逻辑,又能兼容返回falsy值的场景:
1. 封装通用缓存方法工厂函数
最直接的方式是写一个工厂函数,把重复的缓存检查逻辑封装起来,每个需要缓存的方法只需要传入计算逻辑和对应的缓存键即可:
// 通用缓存方法生成器 const createCachedMethod = (computeLogic, cacheKey) => () => { if (typeof this[cacheKey] === "undefined") { this[cacheKey] = computeLogic.call(this); } return this[cacheKey]; }; // 使用示例 class MyClass { // 用私有Symbol作为缓存键,避免和其他属性冲突 #cacheForMyFunc = Symbol('myFuncCache'); #cacheForAnotherFunc = Symbol('anotherFuncCache'); myFunc = createCachedMethod(() => { // 这里写你的计算逻辑,示例返回falsy值 return 0; }, this.#cacheForMyFunc); anotherFunc = createCachedMethod(() => { // 另一个计算逻辑,示例返回falsy值 return ''; }, this.#cacheForAnotherFunc); }
优点:
- 完全复用缓存判断逻辑,每个业务方法只需关注核心计算
- 私有Symbol作为缓存键,彻底避免属性名冲突
- 箭头函数保证
this始终指向类实例,和你原写法逻辑一致
2. 使用装饰器自动处理缓存(需环境支持)
如果你的项目支持ES装饰器(比如用TypeScript或配置Babel),可以写一个@cached装饰器,自动给方法添加缓存能力:
// 缓存装饰器 function cached() { return function(target, propertyKey, descriptor) { // 自动生成唯一缓存键 const cacheKey = `_cache_${propertyKey}`; const originalMethod = descriptor.value; descriptor.value = function() { if (typeof this[cacheKey] === "undefined") { this[cacheKey] = originalMethod.call(this); } return this[cacheKey]; }; return descriptor; }; } // 使用示例 class MyClass { @cached myFunc() { // 计算逻辑,示例返回falsy值 return null; } @cached anotherFunc() { // 另一个计算逻辑,示例返回falsy值 return false; } }
注意:
- 装饰器目前处于ES提案阶段,需要确保项目环境支持
- 若担心字符串缓存键冲突,可改用Symbol生成唯一键
3. 基于基类封装缓存逻辑
如果多个类都有类似缓存需求,可以抽离一个基类,集中管理缓存逻辑:
class CachedBase { _cacheStore = new Map(); getCached(key, computeFn) { if (!this._cacheStore.has(key)) { this._cacheStore.set(key, computeFn.call(this)); } return this._cacheStore.get(key); } } // 使用示例 class MyClass extends CachedBase { myFunc = () => { return this.getCached('myFunc', () => { // 计算逻辑,示例返回falsy值 return 0; }); }; anotherFunc = () => { return this.getCached('anotherFunc', () => { // 计算逻辑,示例返回falsy值 return ''; }); }; }
优点:
- 所有缓存数据集中管理,方便后续扩展缓存清理、过期等功能
- Map的
has方法可准确判断键是否存在,无需担心falsy值干扰
内容的提问来源于stack exchange,提问作者Tyler V.
相关产品推荐
相关产品推荐

