JavaScript中方法重写本质是子类原型上定义同名方法覆盖父类原型方法,遵循就近原则;常用Object.create建立原型链并修正constructor;实例上定义可临时覆盖;class语法是语法糖;禁止修改内置原型。

JavaScript 中用原型链实现方法重写,本质是让子类(或实例)的原型对象上定义一个同名方法,覆盖从父类原型继承来的方法。关键在于“就近原则”:调用时优先查找自身原型上的方法,而不是父类原型上的。
在子构造函数的 prototype 上直接赋值同名方法
这是最常用、最清晰的方式。先让子类继承父类原型,再在其 prototype 上重新定义方法:
- 用 Object.setPrototypeOf(Child.prototype, Parent.prototype) 或更推荐的 Child.prototype = Object.create(Parent.prototype) 建立原型链
- 然后给 Child.prototype.methodName 赋一个新函数
- 别忘了修正 constructor 指针,避免指向错误:Child.prototype.constructor = Child
示例:
function Animal() {}
Animal.prototype.speak = function() {
return "Some sound";
};
function Dog() {}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
// 方法重写
Dog.prototype.speak = function() {
return "Woof!";
};
const dog = new Dog();
console.log(dog.speak()); // "Woof!"(不是 "Some sound")
在实例上定义同名方法(临时覆盖)
如果只希望某个具体实例行为不同,可以直接在该实例上添加方法。由于属性查找先找实例自身,再找原型,所以会“遮蔽”原型上的同名方法:
- 实例自身有该属性(方法)时,不会继续向上查找原型
- 这种方式不影响其他实例,也不影响原型本身
- 适合个性化定制,但不适用于统一修改子类行为
示例:
const cat = new Animal();
cat.speak = function() { return "Meow!"; };
console.log(cat.speak()); // "Meow!"
用 class 语法实现(ES6+,底层仍是原型链)
class 的 extends 和 override(方法重写)本质上是原型链操作的语法糖:
- extends 自动设置子类 prototype 的 [[Prototype]] 指向父类 prototype
- 子类中定义同名方法,自动挂载到子类 prototype 上,完成重写
- 可用 super.methodName() 显式调用父类版本(对应 Parent.prototype.methodName.call(this))
示例:
class Bird extends Animal {
speak() {
return super.speak() + " — chirp!";
}
}
const bird = new Bird();
console.log(bird.speak()); // "Some sound — chirp!"
注意:不要直接修改内置或第三方原型
虽然技术上可以给 Array.prototype.map 重新赋值来“重写”,但这属于危险操作:
- 破坏封装性,影响所有使用该原型的对象
- 可能与其他库冲突,引发难以调试的问题
- 不符合可维护和协作规范
真正需要扩展行为,应使用组合、装饰器或工具函数,而非污染原型。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











