JavaScript中正确重写父类实例方法:子类构造函数先调用super()或Parent.call(this),再在子类原型定义同名方法覆盖,需用super.方法名()或Parent.prototype.方法名.call(this)复用父逻辑。

在 JavaScript 中正确重写父类的实例方法,核心是:子类构造函数中调用 super() 初始化父类实例属性,然后在子类原型上定义同名方法——该方法会自然覆盖父类原型上的同名方法,同时可通过 super.方法名(ES6+ 类语法)或 父类.prototype.方法名.call(this, ...)(函数构造器方式)显式调用父类逻辑。
使用 class 语法时重写方法(推荐)
这是最清晰、最符合语义的方式。子类用 extends 继承,构造函数中必须先调用 super();重写方法时直接在子类中定义同名方法即可,如需复用父类逻辑,用 super.方法名() 调用:
class Animal {
constructor(name) {
this.name = name;
}
speak() {
return `${this.name} makes a sound.`;
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // ✅ 必须先调用,初始化 this
this.breed = breed;
}
// ✅ 正确重写:覆盖父类 speak,同时可选择性调用 super
speak() {
return super.speak().replace('sound', 'bark') + ` (breed: ${this.breed})`;
}
}
const dog = new Dog('Buddy', 'Golden');
console.log(dog.speak());
// → "Buddy makes a bark. (breed: Golden)"
使用函数构造器 + 原型链时重写方法
若仍用传统函数构造器,需手动设置原型链,并确保子类原型继承自父类原型(常用 Object.create(Parent.prototype)),再挂载重写后的方法:
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
return `${this.name} makes a sound.`;
};
function Dog(name, breed) {
Animal.call(this, name); // ✅ 手动调用父构造器
this.breed = breed;
}
// ✅ 正确设置原型链(不可省略)
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
// ✅ 重写方法:直接赋值到子类原型
Dog.prototype.speak = function() {
// ✅ 手动调用父类方法
const parentMsg = Animal.prototype.speak.call(this);
return parentMsg.replace('sound', 'bark') + ` (breed: ${this.breed})`;
};
关键注意事项
-
构造函数中必须先初始化父类:class 中必须
super()在this前;函数构造器中必须Parent.call(this, ...),否则this未定义或不完整。 - 不要直接修改父类原型:重写应在子类原型上进行,避免污染父类及其所有其他子类。
-
箭头函数不能用于重写实例方法:因其没有自己的
this和super,会导致上下文丢失或语法错误。 - 静态方法和实例方法分开处理:重写的是原型上的实例方法;若要重写静态方法,需在类自身(而非原型)上定义同名静态方法。
常见错误示例
以下写法 ❌ 不推荐或会出错:
立即学习“Java免费学习笔记(深入)”;
// 错误1:class 中没调用 super()
class BadDog extends Animal {
constructor(name) {
this.name = name; // ❌ ReferenceError: Must call super constructor
}
}
// 错误2:重写时丢了父类逻辑且无法调用 super(如在普通函数中)
Dog.prototype.speak = function() {
super.speak(); // ❌ SyntaxError:super 只在 class 方法内有效
};
// 错误3:原型链未正确设置(直接赋值导致丢失父类方法)
Dog.prototype = { speak() { ... } }; // ❌ 覆盖整个对象,丢失 Animal.prototype 上所有方法


















