适配器模式核心是委托而非原型链驱动,通过继承目标接口类确立类型关系,构造函数保存被适配对象引用,在方法中显式调用并转换其行为。

JavaScript 中的适配器模式不靠原型链“驱动”,但可以用原型链辅助组织结构、复用逻辑、支持类型检查。核心始终是委托——适配器自己不实现业务,而是把调用转给被适配对象。
明确目标接口与被适配对象
先定义清楚“要变成什么样”和“原本是什么样”。目标接口通常是类或抽象方法占位;被适配对象可以是普通对象、实例或模块。
- 目标接口建议用
class定义,方便后续 instanceof 判断和原型继承 - 被适配对象无需改动,保持原样即可(比如旧日志对象只有
log()) - 例如:
TargetLogger要求有info()、error();而legacyLogger只有log()
用 class 继承建立原型关系
让适配器类继承目标接口类,不是为了复用它的方法逻辑(它通常为空),而是为了获得正确的原型链归属。
- 继承后,
new LoggerAdapter()是TargetLogger的实例,能通过instanceof TargetLogger - 原型上保留空方法占位,语义清晰,也便于 IDE 提示或 TypeScript 类型推导
- 构造函数中保存被适配对象引用,为委托做准备
在方法中显式委托调用
每个目标方法内部,不写新逻辑,而是调用被适配对象对应的方法,并做必要转换(如加前缀、改参数格式)。
-
info(msg)→this.legacy.log('INFO: ' + msg) -
error(msg)→this.legacy.log('ERROR: ' + msg) - 所有行为都来自
this.legacy,不是从父类原型“继承”来的
需要复用时,把通用委托逻辑提到基类原型
如果多个适配器都要对输入做统一处理(比如自动加时间戳、统一格式化),可以把这部分提取到基类原型上。
- 定义
BaseAdapter.prototype.formatMsg = function(type, msg) { ... } - 子类方法里调用
this.formatMsg('info', msg),再传给被适配对象 - 这样既保持委托本质,又避免重复代码,且不破坏单一层级委托关系











