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
英文地址,請注明出處:http://en.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 作為一門靈活且強大的編程語言,其高級特性為開發者提供了極大的創造力和代碼優化空間。本文將圍繞元類、序列化、抽象類與多態等核心高級特性展開,結合豐富的實戰代碼示例,從原理到應用進行全方位解析,幫助你更深入地理解 …