原型链实现装饰器模式本质是动态修改对象方法,在不改动原始构造函数前提下叠加新行为;通过缓存原方法、重写目标方法并插入增强逻辑,支持日志、校验等;推荐仅装饰单个实例以避免污染,复杂场景宜用组合式。

原型链实现装饰器模式,本质是通过修改对象的原型或直接覆盖实例方法,在不改动原始构造函数的前提下,动态叠加新行为。它轻量、无需接口抽象,特别适合 JavaScript 的动态特性,但要注意避免污染原对象和调用顺序混乱。
核心思路:用“旧方法引用 + 新逻辑”重写目标方法
关键不是新建类,而是让对象的方法在执行时先调用原有逻辑,再插入增强代码。常见做法是缓存原始方法,然后重新赋值:
- 获取原方法引用(如 const original = obj.method)
- 用新函数覆盖 obj.method,内部先调用 original.call(this, ...args)
- 在前后自由插入日志、校验、重试等逻辑
典型写法:手写装饰函数封装复用
把装饰逻辑抽成高阶函数,提升可读性和复用性。例如日志装饰器:
function withLog(fn) {
return function(...args) {
console.log(`[LOG] ${fn.name} called with`, args);
const result = fn.apply(this, args);
console.log(`[LOG] ${fn.name} returned`, result);
return result;
};
}
// 应用到对象方法
const player = { fire() { console.log('punch!'); } };
player.fire = withLog(player.fire);
player.fire(); // 输出日志 + punch!
注意原型链装饰的边界与风险
直接操作原型会影响所有实例,需谨慎;而仅装饰单个实例更安全,也更符合“动态增强”的本意:
- ✅ 推荐:只改当前对象的属性(如 obj.method = newFn),不影响其他实例
- ⚠️ 慎用:修改 Constructor.prototype.method,容易引发意外共享
- ❌ 避免:多层装饰时未保存正确原始引用,导致递归或丢失初始行为(如反复覆盖却没缓存第一版)
对比组合式装饰器:何时选原型链?
原型链方式适合简单、临时、脚本级的功能注入;而标准装饰器模式(组合+接口)更适合大型系统中需要类型安全、可测试、可拆卸的场景:
- 快速调试加日志、临时打点监控 → 原型链直接覆盖最省事
- 要支持“加缓存又加鉴权又加重试”,且未来可能开关某一层 → 用组合式装饰器结构更清晰
- 第三方库对象无法改源码,但允许你包装它 → 原型链或闭包装饰都是可行入口











