核心是缩短高频访问路径——限制原型链≤2层,关键属性方法缓存到实例,通用能力改用组合,纯数据用字面量或object.create(null),禁止运行时修改原型。

避免深层原型继承链导致掉帧,核心是让高频访问路径短、稳、可预测——不是消灭继承,而是把关键属性和方法“拉近”到实例层,同时切断不必要的查找跳转。
限制继承深度,强制≤2层结构
现代浏览器(尤其是V8)对超过4层的原型链会逐步放弃内联缓存(IC)优化;10层链下,属性访问比自有属性慢3–5倍,且极易触发主线程卡顿。必须从设计源头收敛:
- 业务类只允许:实例 → 领域基类(如
ChartBase)→Object.prototype(或直接null) - 禁用跨域中间层(如
UIBase → FormBase → ChartBase),领域基类只能单向继承一个稳定基类 - 通用能力(日志、校验、格式化)不靠继承,改用组合:
this.formatter = new DateFormatter()
高频属性/方法必须缓存到实例自身
滚动、动画、事件回调等场景中反复读取this.render或this.id时,每多一层原型查找就多一次内存解引用,直接拖垮帧率。初始化阶段主动“降级”:
- 属性缓存:
this._id = this.id(当id来自原型且在render循环中被读取) - 方法绑定:
this._render = this.render.bind(this)或this._render = Parent.prototype.render - 纯数据对象(如DTO、配置项)不用构造函数,直接用字面量:
{ id: 1, name: 'x' },彻底消除原型链
用Object.create(null)替代默认原型链
对不需要toString、hasOwnProperty等原生方法的纯字典场景(如状态映射表、临时缓存键值对),创建时切断原型链:
-
const cache = Object.create(null)—— 省掉最后一跳,避免__proto__查找开销 - 避免
for...in遍历这类对象;改用Object.keys(cache)或Map - 不与
instanceof混用,也不传给依赖Object.prototype方法的第三方库
禁止运行时修改原型,保持结构稳定
V8的隐藏类(Hidden Class)优化高度依赖原型结构不变。动态增删方法、调用Object.seal()或Object.freeze()会导致IC失效,回退到慢路径:
- 所有原型方法应在定义时一次性写入,不在运行时补丁
- 差异化行为用参数、插件或私有字段控制,而非
Child.prototype.method = ... - 旧代码迁移时,优先封装为独立模块,而非打补丁式覆盖原型











