原型链无属性缓存机制,引擎不记忆属性位置;高频只读属性应挂实例,动态值用weakmap缓存,方法需绑定或引用,原型链深度应≤2层以保性能。

原型链本身不提供属性值缓存机制,JavaScript 引擎(如 V8)也不会记住“某个属性在第几层原型上找到”。所谓“缓存”,其实是通过代码设计让高频访问的值不再依赖运行时查找——本质是把动态查找变成静态持有。
高频只读属性直接挂到实例上
对确定不变、且被频繁读取的属性(比如配置项、主题色、API 地址),在构造函数中一次性计算并赋值给实例,跳过每次查找:
- 配置类属性:`this.apiBase = this.$parent?.config?.apiBase || '/api'`
- 推导类只读值:`this.isDarkMode = this.$parent?.theme === 'dark'`
- 批量挂载:`Object.assign(this, { timeout: 3000, locale: 'zh-CN' })`
动态推导值用 WeakMap 缓存
当属性依赖上下文、无法提前固化(如权限状态、格式化器),又不能每次都走深层原型链时,WeakMap 是最安全的选择:
- 定义全局缓存:
const permissionCache = new WeakMap() - 首次访问时计算并缓存:
if (!permissionCache.has(this)) permissionCache.set(this, this.$user?.role === 'admin') - 后续直接取:
permissionCache.get(this),无原型遍历开销 - WeakMap 自动随对象销毁而清理,适合组件、表单字段等短生命周期对象
方法调用前绑定或缓存引用
原型上的方法每次调用都会触发属性查找。绑定或缓存后,调用直接执行,不查链:
- 绑定实例方法:`this.onSubmit = this.handleSubmit.bind(this)`
- 缓存父类方法引用:`this._render = Parent.prototype.render`(仅限无 this.constructor 依赖的方法)
- 事件处理器尤其适用:避免在渲染循环或高频事件中反复查找
切断冗余链路,减少查找层级
缓存效果受原型链深度制约。V8 在链深 ≥4 层时逐步放弃内联缓存,性能明显下降:
- 纯数据对象(路由表、i18n 字典)用
Object.create(null)创建,彻底跳过Object.prototype - 业务类原型链控制在 ≤2 层:实例 → 业务原型 → null
- 避免多层抽象基类堆叠,改用组合(如
this.formatter = new DateFormatter())











