原型复用有四种方式:1. 直接共用原型对象并修复constructor;2. 用object.create继承父原型;3. 提取公共方法对象混入各prototype;4. 使用es6 class extends实现标准继承。

原型对象在多个构造函数间复用,核心思路是让不同构造函数的 prototype 指向同一个对象(或共享同一套方法定义),从而避免重复创建相同逻辑的方法,节省内存并提升一致性。
直接共用一个原型对象
最简方式是让多个构造函数的 prototype 属性引用同一个对象。这样所有实例都能访问相同的方法,且修改一处即全局生效(需注意副作用):
- 定义一个通用原型对象,集中存放可复用的方法
- 将多个构造函数的 prototype 赋值为该对象
- 注意:此时各构造函数实例的 constructor 会指向同一个函数,需手动修复
示例:
const sharedMethods = {
greet() { return `Hello, ${this.name}`; },
describe() { return `${this.constructor.name}: ${this.name}`; }
};
<p>function User(name) { this.name = name; }
function Admin(name, level) { this.name = name; this.level = level; }</p><p>User.prototype = sharedMethods;
Admin.prototype = sharedMethods;</p><p>// 修复 constructor 指针
User.prototype.constructor = User;
Admin.prototype.constructor = Admin;</p><p>const u = new User('Alice');
const a = new Admin('Bob', 'super');
console.log(u.greet()); // "Hello, Alice"
console.log(a.describe()); // "Admin: Bob"</p>用 Object.create 复用父级原型
当存在层级关系时,可通过 Object.create(Parent.prototype) 让子构造函数继承父构造函数的原型链,实现方法复用与扩展:
- 子构造函数的 prototype 继承自父构造函数的 prototype,保留原型链查找能力
- 可在子 prototype 上添加独有方法,不影响父类
- 避免直接赋值
Child.prototype = Parent.prototype(否则修改会互相污染)
示例:
function Animal(name) { this.name = name; }
Animal.prototype.speak = function() { return `${this.name} makes a sound`; };
<p>function Dog(name, breed) {
Animal.call(this, name);
this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.bark = function() { return <code>${this.name} barks!</code>; };</p><p>const dog = new Dog('Max', 'Golden');
console.log(dog.speak()); // 复用 Animal 的方法
console.log(dog.bark()); // 自有方法</p>提取公共方法到独立对象再混入
不依赖构造函数绑定,把通用行为封装成纯对象,通过 Object.assign 或手动挂载到各 prototype 上:
- 解耦方法定义与构造函数,便于测试和复用
- 各构造函数保持独立的 prototype,互不影响
- 适合无继承关系、但行为相似的类(如 Validator、Logger、Emitter 等)
示例:
const eventable = {
on(event, handler) {
if (!this._events) this._events = {};
if (!this._events[event]) this._events[event] = [];
this._events[event].push(handler);
},
emit(event, ...args) {
const handlers = this._events?.[event];
handlers?.forEach(h => h(...args));
}
};
<p>function Button(text) { this.text = text; }
function Form(id) { this.id = id; }</p><p>Object.assign(Button.prototype, eventable);
Object.assign(Form.prototype, eventable);</p><p>const btn = new Button('Submit');
btn.on('click', () => console.log('clicked'));</p>用 ES6 class + extends 实现标准复用
class 语法本质仍是原型继承,extends 会自动设置子类 prototype 的 [[Prototype]] 指向父类 prototype,是最推荐的现代写法:
- 语义清晰,支持 super 调用、静态方法继承、getter/setter 等
- 底层仍基于 prototype 链,方法自然复用
- 多级继承时链路明确,调试友好
示例:
class Shape {
constructor(color) { this.color = color; }
getColor() { return this.color; }
}
<p>class Circle extends Shape {
constructor(color, radius) {
super(color);
this.radius = radius;
}
getArea() { return Math.PI * this.radius ** 2; }
}</p><p>class Rect extends Shape {
constructor(color, w, h) {
super(color);
this.w = w; this.h = h;
}
getArea() { return this.w * this.h; }
}</p><p>// getColor 方法被 Circle 和 Rect 共享,只存一份</p>Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











