JavaScript可通过属性描述符的get/set实现动态计算与缓存:get用于按需计算或缓存返回,set用于联动清缓存;配合私有字段或WeakMap可安全缓存;复杂场景推荐Proxy+私有字段方案。

JavaScript 中可以通过属性描述符(PropertyDescriptor)配合 get 和 set 访问器,实现属性的动态计算与缓存,既保持调用简洁性(如 obj.prop),又避免重复开销。
用 get 描述符触发按需计算
定义只读的访问器属性,内部执行计算逻辑,每次访问都重新计算——适合结果不随时间/状态变化、或计算成本极低的场景。
- 使用
Object.defineProperty或Object.defineProperties设置get函数 -
get中可读取其他属性、调用方法、甚至发起异步操作(需返回 Promise) - 注意:不能同时设置
value或writable,否则会抛出错误
手动缓存 + get 描述符提升性能
当计算开销较大(如解析 JSON、遍历数组、格式化日期),可在 get 内部用私有字段(如 _cachedProp)暂存结果,首次访问计算并缓存,后续直接返回。
- 缓存键建议结合依赖项(如影响结果的其他属性值)做简单哈希或字符串拼接,避免脏数据
- 若依赖属性可能变更,需在对应
set中清空缓存(例如this._cachedProp = undefined) - 也可用
WeakMap实现实例级私有缓存,避免污染实例属性
用 set 描述符联动更新缓存
当被依赖的源属性改变时,仅靠 get 无法感知。此时配合 set 描述符,在赋值时主动失效相关缓存,保证下次 get 返回最新结果。
立即学习“Java免费学习笔记(深入)”;
- 在
set中检查新旧值是否真正变化(浅比较或自定义逻辑),避免无谓清缓存 - 一个
set可能影响多个派生属性,适合集中管理缓存生命周期 - 注意不要在
set中直接触发复杂计算——应延迟到get时再算
现代替代方案:Proxy 与私有字段组合
对于更复杂的响应式需求(如深层嵌套、批量缓存控制),Proxy 比逐个定义描述符更灵活;搭配 #privateField 可安全封装缓存状态。
-
Proxy的get拦截器可统一处理所有属性的缓存逻辑 - 私有字段(
#cache)避免外部误改,也防止与用户属性名冲突 - 适用于工具类、状态容器等需要透明缓存能力的抽象层


















