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.pswp.cn/diannao/94830.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/94830.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025 年最佳 AI 代理:工具、框架和平台比较

目录 什么是 AI Agents 应用 最佳 AI Agents:综合列表 LangGraph AutoGen CrewAI OpenAI Agents SDK Google Agent Development Kit (ADK) 最佳no-code和open-source AI Agents Dify AutoGPT n8n Rasa BotPress 最佳预构建企业 AI agents Devin AI …

Linux 学习 ------Linux 入门(上)

Linux 是一种自由和开放源代码的类 Unix 操作系统。它诞生于 1991 年,由芬兰程序员林纳斯・托瓦兹(Linus Torvalds)发起并开发。与 Windows 等闭源操作系统不同,Linux 的源代码是公开的,任何人都可以查看、修改和传播&…

[202403-E]春日

[202403-E]春日 题目背景 春水初至, 文笔亦似花开。 题目描述 坐看万紫千红, 提笔洋洋洒洒, 便成篇文章。 现在给你这篇文章, 这篇文章由若干个单词组成, 没有标点符号, 两两单词之间由一个空格隔开。 为了…

Unity笔记(三)——父子关系、坐标转换、Input、屏幕

写在前面写本系列的目的(自用)是回顾已经学过的知识、记录新学习的知识或是记录心得理解,方便自己以后快速复习,减少遗忘。这里只有部分语法知识。九、父子关系1、获取、设置父对象(1)获取父对象可以通过this.transform.parent获取当前对象的父对象Trans…

基于Dubbo的高并发服务治理与流量控制实战指南

基于Dubbo的高并发服务治理与流量控制实战指南 在微服务架构的大规模应用场景中,如何保证服务在高并发压力下的稳定与可用,是每位后端开发者必须面对的挑战。本文结合实际生产环境经验,分享基于Apache Dubbo的高并发服务治理与流量控制方案&a…

Mac 洪泛攻击笔记总结补充

一、Mac 洪泛攻击原理交换机依靠 MAC 地址表来实现数据帧的精准转发,该表记录着端口与相连主机 MAC 地址的对应关系。交换机具备自动学习机制,当收到一个数据帧时,会将帧中的源 MAC 地址与进入的端口号记录到 MAC 表中。同时,由于…

路由器不能上网的解决过程

情况 前段时间,公司来人弄了一下网络后,我的路由器就不能上网了,怎么回事啊。 先看看路由器的情况:看着网络是有连接的:看这上面是能上网的,但是网都是上不去。 奇怪! 路由器介绍 路由器&#x…

Rancher 和 KubeSphere对比

以下是 Rancher 与 KubeSphere 的深度对比,涵盖核心定位、架构设计、功能模块、适用场景等关键维度,助您精准选型:一、核心定位与设计哲学维度RancherKubeSphere本质Kubernetes 多集群管理控制平面Kubernetes 全栈云原生操作系统目标简化K8s集…

【深度学习新浪潮】TripoAI是一款什么样的产品?

TripoAI是由硅谷AI初创公司VAST开发的多模态3D内容生成平台,其核心技术基于数十亿参数的3D基础模型,专注于通过文本描述、单图/多图输入或手绘涂鸦快速生成高精度可编辑的3D模型。以下是其核心信息: 一、技术架构与核心功能 秒级生成与多模态输入 生成速度:仅需8秒即可生成…

二十八天(数据结构:图的补充)

图:是一种非线性结构形式化的描述: G{V,R}V:图中各个顶点元素(如果这个图代表的是地图,这个顶点就是各个点的地址)R:关系集合,图中顶点与顶点之间的关系(如果是地图,这个关系集合可能就代表的是各个地点之间的距离)在顶点与顶点…

户外广告牌识别准确率↑32%:陌讯多模态融合算法实战解析

原创声明本文为原创技术解析,核心技术参数与架构设计引用自《陌讯技术白皮书》,禁止任何形式的转载与抄袭。一、行业痛点:户外广告牌识别的三大技术瓶颈户外广告牌作为城市视觉符号的重要载体,其智能化识别在商业监测、合规监管等…

【vue组件通信】一文了解组件通信多种方式

前言 在 Vue 中,组件通信有多种方式,适用于不同场景(父子组件、兄弟组件、跨级组件等)。以下是完整的组件传值方法总结,仅供概览参考:一、父子组件通信 1. Props(父 → 子) 父组件通…

项目一系列-第3章 若依框架入门

第3章 若依框架入门 3.1 若依框架概述 为什么要基于若依框架开发? 快速开发:能快速搭建一个应用框架,减少工作量。可定制化:提供丰富插件和拓展点,满足不同项目的特定需求。简化开发流程:框架提供常用的功能…

WSL安装MuJoco报错——FatalError: gladLoadGL error

文章目录WSL中配置MuJoCo报错 FatalError: gladLoadGL error 的终极解决方案🔍 问题原因分析✅ 解决方案:切换至 EGL 渲染后端第一步:安装系统级依赖库第二步:使用 Conda 安装兼容的图形库第三步:设置环境变量以启用 E…

2025产品经理接单经验分享与平台汇总

产品和开发永远是一家,如此说来产品和开发接单的经验和平台其实大差不差,今天刚好看到后台有人咨询产品经理接单的问题,索性直接写一篇文章好了。 目录 一、产品经理接单的三个关键建议 1、能力产品化,比履历更重要 2、合同、…

BGP协议笔记

一、BGP协议(边界网关协议) 是一种用于自治系统间的动态路由协议,是一种外部网关(EGP)协议。负责在不同自治系统(AS)之间交换路由信息,目的是实现大规模网络的可扩展性、策略控制和稳定性。 自治系统AS:一组被进行统…

Ⅹ—6.计算机二级综合题27---30套

第27套 【填空题】 给定程序中,函数fun的功能是:计算形参x所指数组中N个数的平均值(规定所有数均为正数),将所指数组中小于平均值的数据依次移至数组的前部,大于等于平均值的数据依次移至x所指数组的后部,平均值作为函数值返回,在主函数中输出平均值和移动后的数据。 …

GDB 调试全方位指南:从入门到精通

在程序开发中,调试是定位和解决问题的核心环节。GDB (GNU Debugger) 作为一款功能强大的命令行调试器,是Linux环境下C/C开发者的必备利器。本文将系统讲解GDB的使用方法,涵盖基础操作到高级技巧,助你高效排错。一、基础准备&#…

Python:从元类到多态的实战指南

Python 作为一门灵活且强大的编程语言,其高级特性为开发者提供了极大的创造力和代码优化空间。本文将围绕元类、序列化、抽象类与多态等核心高级特性展开,结合丰富的实战代码示例,从原理到应用进行全方位解析,帮助你更深入地理解 …