原型链中“重写”的本质是运行时拦截调用并注入新行为,而非静态覆盖:1. 实例方法重写仅影响当前对象;2. 子类原型重写需显式调用父类逻辑;3. 装饰器函数支持复用与组合;4. 需注意this绑定、副作用、异步处理及循环调用。

在原型链中实现类似“重写”的动态逻辑,关键不是静态覆盖方法,而是运行时按需干预方法执行流程——本质是拦截调用、注入新行为,同时保留原有逻辑的可调用性。
直接覆盖实例方法(轻量、单次有效)
适用于临时增强某个对象,不污染构造函数或原型:
- 先缓存原方法:
const original = obj.doSomething - 再重新赋值:
obj.doSomething = function(...args) { console.log('before'); const result = original.call(this, ...args); console.log('after'); return result; }; - 注意:只影响当前对象,不影响其他实例,也无需修改原型
在子类原型上重写并调用父类(标准继承场景)
适合有明确父子关系、需要复用并扩展行为的结构:
- 子类原型定义同名方法,自动屏蔽父类同名方法
- 如需复用父逻辑,显式调用:
Parent.prototype.method.call(this, ...args) - ES6 中可用
super.method(),语义更清晰,且能正确绑定 this
用装饰器函数封装重写逻辑(复用性强)
把“重写”变成可配置、可组合的操作:
- 写一个高阶函数,比如
function logDecorator(fn) { return function(...args) { console.log('call', fn.name); return fn.apply(this, args); }; } - 应用时:
obj.method = logDecorator(obj.method); - 支持叠加:
obj.method = retryDecorator(throttleDecorator(obj.method))
避免踩坑的几个重点
动态重写容易出问题,以下细节必须留意:
-
this 绑定要准确:用
call或apply显式传入,否则原方法内部的this会丢失 - 不要直接改 prototype 上的方法(除非你明确想影响所有实例),否则可能引发意料外的副作用
- 异步方法要小心返回值和错误捕获:原方法返回 Promise 时,装饰逻辑需 await 或 .then 链式处理
- 避免循环调用:比如在重写函数里又调用了自己未缓存的原引用,会导致栈溢出

















