当前位置: 首页 > news >正文

Javascript中的一些常见设计模式

1. 单例模式(Singleton Pattern)

核心思想

  • 一个类只能有一个实例,并提供一个全局访问点。

场景

  • 全局缓存
  • Vuex / Redux 中的 store
  • 浏览器中的 localStorage 管理类

示例

const Singleton = (function () {let instance;function createInstance() {return { name: "我是唯一的实例" };}return {getInstance: function () {if (!instance) {instance = createInstance();}return instance;}};
})();const a = Singleton.getInstance();
const b = Singleton.getInstance();
console.log(a === b); // true

2. 工厂模式(Factory Pattern)

核心思想

  • 不直接使用 new 去创建对象,而是通过一个工厂函数根据条件返回不同的实例。

场景

  • 创建大量结构相似的对象
  • 根据不同参数创建不同对象

示例

function AnimalFactory(type) {switch (type) {case 'dog':return { sound: () => console.log("汪汪") };case 'cat':return { sound: () => console.log("喵喵") };default:return { sound: () => console.log("未知动物") };}
}const dog = AnimalFactory('dog');
dog.sound(); // 汪汪//封装new
function AnimalFactory(type) {if (type === 'dog') return new Dog();if (type === 'cat') return new Cat();throw new Error("Unknown type");
}const pet1 = AnimalFactory('dog'); // 外部不再直接 new
const pet2 = AnimalFactory('cat');

3. 策略模式(Strategy Pattern)

核心思想

  • 定义一系列算法,把它们封装起来,并且可以互相替换。

场景

  • 表单验证
  • 多种支付方式选择
  • AI 策略切换

示例

const strategies = {isNotEmpty: val => val !== '',isMobile: val => /^1[3-9]\d{9}$/.test(val),minLength: (val, len) => val.length >= len
};function validate(rule, val, ...args) {return strategies[rule](val, ...args);
}console.log(validate('isMobile', '13888888888')); // true

4. 观察者模式(Observer Pattern)

核心思想

  • 对象维护一个观察者列表,当自身状态发生变化时,主动通知这些观察者。
  • 解耦发布者与订阅者之间的关系,实现一对多的通知机制。

角色

  • Subject(目标对象):被观察的对象,维护一个观察者列表
  • Observer(观察者):订阅目标对象的变化,目标对象变化后会通知观察者

场景

  • Vue 的响应式数据
  • 发布订阅
  • DOM 事件系统

示例

class Subject {constructor() {this.observers = [];}addObserver(observer) {this.observers.push(observer);}notify(data) {this.observers.forEach(observer => observer.update(data));}
}class Observer {constructor(name) {this.name = name;}update(data) {console.log(`${this.name} 收到通知:`, data);}
}const subject = new Subject();
subject.addObserver(new Observer("A"));
subject.addObserver(new Observer("B"));subject.notify("状态变更啦!"); 
//A 收到通知: 状态变更啦!
//B 收到通知: 状态变更啦!

5.中介者模式(Mediator Pattern)

核心思想

  • 避免多个对象之间形成网状结构,实现对象之间的解耦协作。

角色

  • Mediator(中介者):封装对象之间的通信,处理对象之间的交互逻辑
  • Colleague(同事类):不再相互通信,而是和中介者打交道

示例

class Mediator {constructor() {this.users = {};}register(user) {this.users[user.name] = user;user.mediator = this;}send(message, from, to) {if (this.users[to]) {this.users[to].receive(message, from);}}
}class User {constructor(name) {this.name = name;this.mediator = null;}send(message, to) {this.mediator.send(message, this.name, to);}receive(message, from) {console.log(`${this.name} 收到来自 ${from} 的消息: ${message}`);}
}const mediator = new Mediator();
const alice = new User("Alice");
const bob = new User("Bob");mediator.register(alice);
mediator.register(bob);alice.send("Hi Bob", "Bob");

6. 装饰器模式(Decorator Pattern)

核心思想

  • 不修改原有对象结构的前提下,动态扩展其功能。

场景

  • Vue 的组件装饰器(@Component)
  • 对函数、方法添加日志、缓存、权限控制等

示例

function logDecorator(fn) {return function (...args) {console.log("调用前:", args);const result = fn.apply(this, args);console.log("调用后:", result);return result;}
}function sum(a, b) {return a + b;
}const decoratedSum = logDecorator(sum);
decoratedSum(1, 2);
// 调用前:[1, 2]
// 调用后:3

7. 代理模式(Proxy Pattern)

核心思想

  • 通过一个代理对象控制对另一个对象的访问。

场景

  • 数据拦截与监控(如 Vue3 响应式 Proxy)
  • 图片懒加载
  • 网络请求代理

示例

const target = {name: "qiqi",age: 28
};const proxy = new Proxy(target, {get(obj, prop) {console.log("访问属性:", prop);return obj[prop];},set(obj, prop, value) {console.log(`设置 ${prop}${value}`);obj[prop] = value;return true;}
});proxy.name;       // 访问属性:name
proxy.age = 30;   // 设置 age 为 30

8. 外观模式(Facade Pattern)

核心思想

  • 提供一个统一的接口,屏蔽复杂系统的内部细节。

场景

  • 封装复杂 API
  • 统一调用入口
  • 浏览器兼容性封装

示例

function ajaxFacade(url, method, data) {return fetch(url, {method,headers: { 'Content-Type': 'application/json' },body: JSON.stringify(data)}).then(res => res.json());
}// 使用
ajaxFacade('/api/login', 'POST', { name: 'qiqi' });

9. 发布订阅模式(Publish-Subscribe Pattern)

核心思想

  • 通过事件中心管理多个对象之间的通信,发布者与订阅者之间不直接关联。

与观察者模式类似,但通过中间调度器来解耦。

场景

  • 事件总线 EventBus
  • 跨组件通信
  • 消息队列

示例:JS 中的自定义实现

const EventBus = {events: {},on(event, handler) {if (!this.events[event]) this.events[event] = [];this.events[event].push(handler);},emit(event, data) {(this.events[event] || []).forEach(fn => fn(data));}
};EventBus.on('login', data => console.log("登录成功:", data));
EventBus.emit('login', { user: 'qiqi' }); //登录成功: { user: 'qiqi' }

在 Vue 中用法

创建 EventBus 实例:

// event-bus.js
import Vue from 'vue';
export const EventBus = new Vue();

在组件 A 中监听事件(订阅):

// ComponentA.vue
import { EventBus } from './event-bus';export default {created() {EventBus.$on('sayHello', (msg) => {console.log('收到消息:', msg);});},beforeDestroy() {EventBus.$off('sayHello'); // 清除监听}
}

在组件 B 中发送事件(发布):

// ComponentB.vue
import { EventBus } from './event-bus';export default {methods: {sendMsg() {EventBus.$emit('sayHello', '你好,我是B组件');}}
}

Vue 源码中的 EventsMixin (精简):

function EventsMixin(Vue) {Vue.prototype.$on = function (event, fn) {const vm = this;if (!vm._events) vm._events = {};if (!vm._events[event]) vm._events[event] = [];vm._events[event].push(fn);}Vue.prototype.$emit = function (event, ...args) {const vm = this;const cbs = vm._events && vm._events[event];if (cbs) {cbs.forEach(cb => cb(...args));}}Vue.prototype.$off = function (event, fn) {const vm = this;if (!vm._events) return;// 省略部分逻辑,只保留关键流程if (!fn) {delete vm._events[event];} else {vm._events[event] = vm._events[event].filter(cb => cb !== fn);}}
}

Vue2 中常用的设计模式

  1. 观察者模式(Observer Pattern)
    • 用途:实现响应式系统。
    • 核心机制:Dep 和 Watcher。
      • 数据变化 → 通知订阅者(watcher) → 更新视图。

关键代码:

Object.defineProperty(obj, 'key', {get() {// 依赖收集},set(newVal) {// 通知 watcher 更新}
});
  1. 发布-订阅模式(Publish-Subscribe)

    • 用途:事件总线(EventBus)。
      • 用于组件间通信,特别是没有父子关系的组件。
    • 实现方式:通过 $on、$emit、$off 方法注册、触发和注销事件。
  2. 工厂模式(Factory Pattern)

    • 用途:创建组件实例、VNode 等。
    • 示例:Vue.extend() 实际上就是创建一个“组件构造器”。

Vue3 中常用的设计模式

  1. 观察者模式(Observer Pattern)
    • 用途:响应式系统升级为 Proxy。
    • 与 Vue2 区别:用 Proxy 替代了 Object.defineProperty,更强大、无死角。
    • 核心机制:effect()、reactive()、track()、trigger()。
  2. 组合模式(Composite Pattern)
    • 用途:组合式 API(Composition API)。
      • 将逻辑组合成小函数(setup() 中的 hooks),类似树状结构组织功能逻辑。
      • 更灵活地组合复用功能。
  3. 代理模式(Proxy Pattern)
    • 用途:响应式对象封装。
const state = reactive({ count: 0 });

reactive 返回的对象是 Proxy 的代理,拦截读写操作。

  1. 依赖注入模式(DI Pattern)
    • 用途:通过 provide / inject 实现跨层级组件通信。
  2. 策略模式(Strategy Pattern)
    • 用途:compiler 和 patch 阶段,Vue 会根据不同平台(Web、SSR、Native)选择不同策略处理渲染。
http://www.dtcms.com/a/322174.html

相关文章:

  • 小程序中使用echarts(2025/8/8)
  • 最近看到的提示词相关内容汇总
  • Document Picture-in-Picture API拥抱全新浮窗体验[参考:window.open]
  • K-Means 聚类
  • 液体泄漏识别误报率↓76%:陌讯多模态融合算法实战解析
  • 94、【OS】【Nuttx】【构建】cmake 配置介绍
  • 【Linux】Linux增删改查命令大全(附频率评级)
  • 批量将NC格式数据转换为TIF格式:解决转换后图像颠倒、镜像、翻转等问题
  • 深度剖析主流AI大模型的编程语言与架构选择:行业实践与技术细节解读
  • Uipath Studio中爬取网页信息
  • 安装CST时,报错问题处理
  • 几个概率分布在机器学习应用示例
  • Java-反射
  • C++编程之旅-- -- --类与对象的奇幻征途之初识篇(一)(了解类的基本用法,计算类大小,分析this指针)
  • 【完整源码+数据集+部署教程】海洋物体实例分割系统源码和数据集:改进yolo11-EfficientHead
  • Java【问题 07】SSH不同版本使用jsch问题处理(7.4升级9.7及欧拉原生8.8)
  • WD5202 非隔离降压转换芯片,220V降5V,输出电流80MA
  • Java学习Collection单列集合中的三种通用遍历方法
  • 【Erdas实验教程】029:遥感图像光谱增强(缨帽变换)
  • 经济学从业者职业发展认证体系分析
  • 在 Git 中,将本地分支的修改提交到主分支
  • 数据结构--哈希表与排序、选择算法
  • PVE 9.0 保姆级安装及优化教程(换源、网络配置、远程唤醒等)【基础篇】
  • 农行鉴权问题
  • 嵌入式 Linux 驱动开发常见问题排查宝典(驱动开发篇)v1.0
  • “人工”智能究竟需要多少人工?
  • 《设计模式之禅》笔记摘录 - 14.组合模式
  • 使用Python+selenium实现第一个自动化测试脚本
  • 【GPT-OSS 全面测评】释放推理、部署和自主掌控的 AI 新纪元
  • 1688 图片搜图找货接口开发实战:从图像特征提取到商品匹配全流程