JavaScript 设计模式是在软件开发中针对常见问题的可复用解决方案。由于 JavaScript 是动态、原型继承、支持函数式与面向对象的多范式语言许多传统设计模式在 JavaScript 中既有经典实现也有更简洁的现代实现。1. 设计模式分类通常参考 GoFGang of Four的 23 种设计模式分为三大类1创建型对象创建机制2结构型对象组合与类之间的关系3行为型对象之间的职责分配与通信在 JavaScript 中由于函数是一等公民、闭包、原型链等特性有些模式实现更为灵活。2. 创建型模式2.1 单例模式Singleton确保一个类只有一个实例并提供全局访问点。实现利用闭包或Symbol控制实例。const Singleton (function() { let instance; function createInstance() { return { data: single instance }; } return { getInstance: function() { if (!instance) instance createInstance(); return instance; } }; })(); // ES6 类方式 class SingletonClass { constructor() { if (!SingletonClass.instance) { SingletonClass.instance this; } return SingletonClass.instance; } }2.2 工厂模式Factory Method将对象的创建与使用分离通过一个函数返回不同类型的对象。function Car(brand) { this.brand brand; } function Bike(brand) { this.brand brand; } function vehicleFactory(type, brand) { switch(type) { case car: return new Car(brand); case bike: return new Bike(brand); default: throw new Error(Unknown type); } }抽象工厂一组工厂方法创建一系列相关对象。2.3 建造者模式Builder将复杂对象的构建过程分步完成与表示分离。class Burger { constructor(builder) { this.size builder.size; this.cheese builder.cheese; } static Builder class { constructor(size) { this.size size; } addCheese() { this.cheese true; return this; } build() { return new Burger(this); } } } const myBurger new Burger.Builder(large).addCheese().build();2.4 原型模式Prototype通过克隆已有对象来创建新对象利用 JavaScript 的原型链。const carPrototype { init(brand) { this.brand brand; return this; }, drive() { console.log(Driving ${this.brand}); } }; const myCar Object.create(carPrototype).init(Tesla); // 或使用 ES6 类继承自动实现原型模式3. 结构型模式3.1 适配器模式Adapter将一个类的接口转换成客户期望的另一个接口解决接口不兼容。class OldAPI { request() { return old data; } } class NewAPI { fetch() { return new data; } } // 适配器 class Adapter { constructor(newAPI) { this.newAPI newAPI; } request() { return this.newAPI.fetch(); } }3.2 装饰器模式Decorator动态给对象添加额外职责不修改原有结构。JavaScript 中常用高阶函数或类装饰器提案阶段。function withLogging(fn) { return function(...args) { console.log(Calling ${fn.name}); return fn(...args); }; } const add (a,b) ab; const loggedAdd withLogging(add);3.3 代理模式Proxy为另一个对象提供替身或占位符控制对其的访问。ES6 原生Proxy可直接实现。const target { message: hello }; const handler { get(obj, prop) { if (prop message) return obj[prop].toUpperCase(); return obj[prop]; } }; const proxy new Proxy(target, handler); console.log(proxy.message); // HELLO3.4 外观模式Facade为复杂子系统提供统一的简化接口。class CPU { freeze() { /*...*/ } jump() { /*...*/ } execute() { /*...*/ } } class Memory { load() { /*...*/ } } class ComputerFacade { constructor() { this.cpu new CPU(); this.memory new Memory(); } start() { this.cpu.freeze(); this.memory.load(); this.cpu.jump(); this.cpu.execute(); } }3.5 组合模式Composite将对象组合成树形结构以表示“部分-整体”层次使单个对象和组合对象有一致接口。class Graphic { draw() {} } class Circle extends Graphic { draw() { console.log(draw circle); } } class CompositeGraphic extends Graphic { constructor() { super(); this.graphics []; } add(g) { this.graphics.push(g); } draw() { this.graphics.forEach(g g.draw()); } }4. 行为型模式4.1 观察者模式Observer与发布订阅Publish/Subscribe定义对象间的一对多依赖当主题变化时通知所有观察者。发布订阅通过中间代理进一步解耦。观察者Subject 直接持有 Observer 列表class Subject { constructor() { this.observers []; } attach(observer) { this.observers.push(observer); } notify(data) { this.observers.forEach(obs obs.update(data)); } } class Observer { update(data) { console.log(received, data); } }发布订阅事件中心const EventBus { events: {}, subscribe(event, callback) { if (!this.events[event]) this.events[event] []; this.events[event].push(callback); }, publish(event, data) { if (this.events[event]) this.events[event].forEach(cb cb(data)); } };4.2 策略模式Strategy定义一系列算法使其可以互相替换算法的变化独立于使用算法的客户。const strategies { plus: (a,b) ab, minus: (a,b) a-b, }; function execute(strategy, a, b) { return strategies[strategy](a,b); } console.log(execute(plus, 5, 3)); // 84.3 命令模式Command将请求封装为对象从而支持参数化、队列、日志、撤销等。class Light { turnOn() { console.log(light on); } } class TurnOnCommand { constructor(light) { this.light light; } execute() { this.light.turnOn(); } } class RemoteControl { setCommand(cmd) { this.command cmd; } pressButton() { this.command.execute(); } }4.4 迭代器模式Iterator提供一种方法顺序访问聚合对象中的元素而不暴露其内部表示。JavaScript 内置Symbol.iterator支持。const myIterable { items: [1,2,3], [Symbol.iterator]() { let index 0; return { next: () ({ value: this.items[index], done: index this.items.length }) }; } }; for (let val of myIterable) console.log(val);4.5 中介者模式Mediator用一个中介对象封装一系列对象之间的交互使对象不必显式相互引用。class Mediator { constructor() { this.colleagues []; } register(c) { this.colleagues.push(c); c.mediator this; } send(sender, msg) { this.colleagues.forEach(c { if (c ! sender) c.receive(msg); }); } } class Colleague { constructor(name) { this.name name; } send(msg) { this.mediator.send(this, msg); } receive(msg) { console.log(${this.name} got ${msg}); } }4.6 状态模式State允许对象在其内部状态改变时改变其行为看起来像是修改了它的类。class Context { constructor() { this.state new StateA(); } setState(state) { this.state state; } request() { this.state.handle(this); } } class StateA { handle(ctx) { console.log(state A); ctx.setState(new StateB()); } } class StateB { handle(ctx) { console.log(state B); ctx.setState(new StateA()); } }4.7 模板方法模式Template Method在父类中定义算法的骨架让子类实现具体步骤。class Beverage { boilWater() { console.log(boil water); } brew() { throw new Error(must override); } pourInCup() { console.log(pour in cup); } addCondiments() { throw new Error(must override); } prepare() { this.boilWater(); this.brew(); this.pourInCup(); this.addCondiments(); } } class Coffee extends Beverage { brew() { console.log(brew coffee); } addCondiments() { console.log(add sugar); } }5. JavaScript 特有的设计模式5.1 模块模式Module Pattern利用立即执行函数表达式IIFE或 ES6 模块实现私有变量和封装。// IIFE 模块 const module (function() { let privateVar 0; function privateMethod() {} return { publicMethod() { privateVar; } }; })(); // ES6 模块 (文件) // export const publicVar 1; // export function publicMethod() {}5.2 混入模式Mixin将多个对象的属性和方法混合到一个对象实现多重继承的效果。const mixin { sayHi() { console.log(Hi, Im ${this.name}); } }; class Person { constructor(name) { this.name name; } } Object.assign(Person.prototype, mixin);5.3 高阶组件模式React 等框架中常见在 React 中通过函数接收组件并返回增强后的新组件属于装饰器模式的一种应用。6. 现代 JavaScript 对设计模式的影响1ES6 类简化了构造函数、继承和super调用使传统面向对象模式如工厂、建造者更易读。2Proxy 与 Reflect原生支持代理模式可实现元编程、数据劫持等。3模块系统原生模块import/export取代了以往的 IIFE 模块模式。4箭头函数简化回调在策略模式、观察者模式中更简洁。5Symbol可用于定义私有属性通过Symbol.for或防止属性名冲突。6Decorator 提案未来可能提供标准的装饰器语法简化装饰器模式。7. 总结设计模式是解决特定问题的经验总结但使用时应注意1不要过度设计在简单场景下直接实现可能比套用模式更合适。2结合语言特性JavaScript 的动态性允许用更简单的方式实现很多模式如函数代替策略类。3保持代码可读性模式名称可作为代码注释帮助团队理解意图。深入理解设计模式能帮助写出更健壮、可维护的 JavaScript 代码。在实际项目中常用模式如单例、观察者、策略、模块几乎无处不在值得熟练掌握。