0

0

为什么需要学习javascript设计模式_如何实现单例和观察者模式【教程】

夜晨

夜晨

发布时间:2026-01-28 13:49:11

|

542人浏览过

|

来源于php中文网

原创

JavaScript设计模式应在代码量超3000行、多人协作或频繁连锁崩溃时使用;单例确保全局唯一实例,观察者解耦事件通知,二者组合构成状态管理库核心。

为什么需要学习javascript设计模式_如何实现单例和观察者模式【教程】

JavaScript 设计模式不是为了炫技,而是当代码量超过 3000 行、多人协作修改同一模块、或者频繁出现“改一处崩三处”时,你才真正需要它。单例和观察者模式尤其高频——前者管全局状态的唯一性,后者解耦事件通知逻辑。

单例模式:如何确保一个类只生成一个实例

常见错误是直接用 const instance = new MyClass(),看似只创建一次,但模块被多次 import 时(尤其在 Webpack 的 HMR 或测试环境里),instance 可能被重复初始化。真正的单例必须控制构造入口。

  • 用闭包 + 静态属性是最稳妥的方式:
    class Logger {
      constructor() {
        if (Logger.instance) return Logger.instance;
        this.logs = [];
        Logger.instance = this;
      }
    }
    // 使用时始终调用 new,内部拦截
    const logger1 = new Logger();
    const logger2 = new Logger();
    console.log(logger1 === logger2); // true
  • ES6 模块天然单例,更推荐导出实例而非类:
    // logger.js
    export const logger = new (class {
      constructor() { this.logs = []; }
    })();
    这样无论多少个文件 import { logger },拿到的都是同一个对象
  • 注意:如果类依赖外部参数(如配置项),不能简单用 if (Logger.instance),得加判断逻辑或改用工厂函数封装初始化条件

观察者模式:如何避免组件间硬编码调用

典型场景是表单校验后通知提交按钮更新状态,或 WebSocket 收到消息后刷新多个视图。直接写 button.update(); chart.redraw(); 会导致高度耦合,改一个就要动一堆地方。

  • 核心是分离“谁发消息”和“谁收消息”:
    class EventEmitter {
      constructor() { this.events = {}; }
      on(type, fn) {
        this.events[type] = this.events[type] || [];
        this.events[type].push(fn);
      }
      emit(type, data) {
        (this.events[type] || []).forEach(fn => fn(data));
      }
    }
  • 实际使用中,不要让业务逻辑直接依赖 EventEmitter 类,而是封装成语义化事件:
    // auth.js
    export const authBus = new EventEmitter();
    // login.js
    authBus.emit('login-success', { token, user });
    // header.js
    authBus.on('login-success', ({ user }) => updateAvatar(user));
  • 容易漏掉的是取消监听 —— 组件卸载时必须调用 off() 或用 WeakMap 管理 listener 生命周期,否则引发内存泄漏。现代框架(React/Vue)的 effect cleanup 就是干这个的

单例 + 观察者组合:为什么全局状态管理库都这么写

Redux storePinia 实际就是单例 + 观察者混合体:store 是唯一实例,subscribe 就是观察者注册。自己手写时最容易忽略的是事件触发时机和同步/异步边界。

Dang.ai
Dang.ai

Dang.ai是一个AI工具目录集,已收集超过5000+ AI工具

下载

立即学习Java免费学习笔记(深入)”;

  • 同步 emit 容易导致“通知过程中又触发新通知”,形成调用栈爆炸;建议加队列或用 Promise.resolve().then(() => emit()) 推迟到微任务
  • 单例对象若暴露了可写属性(如 store.state = {}),外部直接改会导致观察者无法捕获变化 —— 必须配合 Object.freeze 或 Proxy 拦截 set
  • Node.js 环境下要注意 CommonJS 和 ESM 模块缓存机制差异:ESM 的 export default 是活绑定,CommonJS 的 module.exports 是值拷贝,混用时单例可能失效

真正难的不是写出符合 UML 图的模式代码,而是判断什么时候不该用——比如两个函数只在同一个文件里调用,硬套观察者反而增加理解成本。模式是工具,不是教条。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
es6新特性
es6新特性

es6新特性有:1、块级作用域变量;2、箭头函数;3、模板字符串;4、解构赋值;5、默认参数;6、 扩展运算符;7、 类和继承;8、Promise。本专题为大家提供es6新特性的相关的文章、下载、课程内容,供大家免费下载体验。

103

2023.07.17

es6新特性有哪些
es6新特性有哪些

es6的新特性有:1、块级作用域;2、箭头函数;3、解构赋值;4、默认参数;5、扩展运算符;6、模板字符串;7、类和模块;8、迭代器和生成器;9、Promise对象;10、模块化导入和导出等等。本专题为大家提供es6新特性的相关的文章、下载、课程内容,供大家免费下载体验。

195

2023.08.04

JavaScript ES6新特性
JavaScript ES6新特性

ES6是JavaScript的根本性升级,引入let/const实现块级作用域、箭头函数解决this绑定问题、解构赋值与模板字符串简化数据处理、对象简写与模块化提升代码可读性与组织性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

221

2025.12.24

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

776

2023.08.22

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

530

2023.09.20

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

395

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

575

2023.08.10

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

395

2023.07.18

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

84

2026.01.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Vue 教程
Vue 教程

共42课时 | 7.3万人学习

Vue3.x 工具篇--十天技能课堂
Vue3.x 工具篇--十天技能课堂

共26课时 | 1.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号