将共享方法定义在原型上可避免重复创建函数,显著降低内存占用和初始化开销;错误是在构造函数内定义方法导致每个实例独占副本,正确是统一挂载到prototype。

直接在原型上定义方法,避免每个实例重复创建函数,能显著降低内存占用和初始化开销。这是 JavaScript 原型机制最核心的性能价值之一。
把共享方法挂到原型上
当批量创建大量相似对象(如粒子、图形节点、数据项)时,若在构造函数内定义方法,每个实例都会持有独立函数副本,浪费内存且拖慢创建速度。
- ❌ 错误写法:每次 new 都生成新函数
this.x = x;
this.y = y;
this.move = function(dx, dy) { // 每个实例都新建一份
this.x += dx;
this.y += dy;
};
}
- ✅ 正确写法:共用原型方法
this.x = x;
this.y = y;
}
Particle.prototype.move = function(dx, dy) { // 所有实例共享同一函数
this.x += dx;
this.y += dy;
10 万个 Particle 实例可节省数 MB 内存,并加快初始化速度。
避免原型链过长影响属性访问
频繁读取属性时,若原型链太深,查找开销会累积。尤其在密集循环中(如 Canvas 像素处理),应确保常用属性直接挂在实例上,而非层层向上查找。
- 保持关键字段为自有属性(own property),比如 x、y、id
- 不要把数值计算中间量或配置项放在 Object.prototype 或多层继承链上
- 可用 Object.hasOwn(instance, 'prop') 快速判断是否为自有属性,避免 in 操作符遍历整个原型链
慎用动态添加原型方法
运行时修改原型(如 SomeClass.prototype.newMethod = ...)会触发 V8 引擎的隐藏类失效(deoptimization),导致已创建的实例失去 JIT 优化,大幅降低执行效率。
- 所有原型方法应在类定义完成时一次性声明完毕
- 避免在循环、事件回调或高频路径中动态扩展原型
- 若需条件逻辑,用分支判断封装在已有方法内,而非增删原型方法
配合 Object.freeze 与构造函数优化
对只读配置类或工具类,冻结其原型可提升引擎优化信心:
- Object.freeze(Particle.prototype) 告诉引擎该原型不会再被修改,有助于内联和常量折叠
- 构造函数尽量保持轻量,不做复杂计算或异步操作;重逻辑移入原型方法或单独服务模块
- 使用 class 语法时,方法默认定义在原型上,但注意箭头函数写法会破坏 this 绑定,仍需显式绑定或改用普通方法
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











