javascript设计模式有哪些_如何实现一个简单的单例模式?

16次阅读

单例模式确保一个类只有一个实例并提供全局访问点,核心是控制创建时机、防止重复初始化、保证多次调用返回同一对象;常用实现包括闭包缓存、es6 class 静态属性及惰性安全的私有静态属性方式。

javascript设计模式有哪些_如何实现一个简单的单例模式?

javaScript 中常用的设计模式包括单例模式、工厂模式、观察者模式(发布-订阅)、策略模式、代理模式、装饰器模式、适配器模式、命令模式、状态模式等。其中单例模式最常用于管理全局唯一实例,比如配置管理器、日志记录器、弹窗控制器等。

单例模式的核心要点

单例模式确保一个类只有一个实例,并提供一个全局访问点。关键在于:控制实例的创建时机、防止重复初始化、保证多次调用返回同一对象。

基础实现:使用闭包和变量缓存

这是最简洁、易理解的方式,利用立即执行函数封装私有变量,避免污染全局作用域

const Singleton = (function() {   let instance = null; 

function createInstance() { return { name: 'Singleton Instance', getId: () => Math.random().toString(36).substr(2, 9) }; }

return { getInstance: function() { if (!instance) { instance = createInstance(); } return instance; } }; })();

// 使用 const a = Singleton.getInstance(); const b = Singleton.getInstance(); console.log(a === b); // true

ES6 Class + 静态属性方式(更现代)

借助 class 语法和静态属性,语义更清晰,也便于扩展:

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

class Logger {   constructor() {     if (Logger.instance) {       return Logger.instance;     }     this.logs = [];     Logger.instance = this;   } 

log(message) { this.logs.push([${new Date().toISOString()}] ${message}); }

getLogCount() { return this.logs.length; } }

// 手动初始化一次(或在首次调用时惰性初始化) Logger.instance = null;

// 使用 const logger1 = new Logger(); const logger2 = new Logger(); console.log(logger1 === logger2); // true

惰性安全的 Class 单例(推荐)

把实例创建逻辑完全封装在类内部,外部无需关心初始化细节:

class DatabaseConnection {   static #instance = null; 

constructor() { if (DatabaseConnection.#instance) { return DatabaseConnection.#instance; } this.connectionId = conn_${Date.now()}_${Math.random().toFixed(4)}; DatabaseConnection.#instance = this; }

static getInstance() { if (!DatabaseConnection.#instance) { DatabaseConnection.#instance = new DatabaseConnection(); } return DatabaseConnection.#instance; }

query(sql) { console.log(Executing: ${sql} on ${this.connectionId}); } }

// 使用 const db1 = DatabaseConnection.getInstance(); const db2 = DatabaseConnection.getInstance(); console.log(db1 === db2); // true db1.query('SELECT * FROM users');

注意事项与常见误区

  • 避免直接 new 多次——必须通过 getInstance 或静态方法获取实例
  • 构造函数内不能做耗时或副作用操作(如发起网络请求),除非明确需要且已做惰性处理
  • 如果涉及异步初始化(如加载配置),需配合 promise 和状态标记,不能简单用 if 判断
  • 单例不是万能的,过度使用会增加模块耦合,测试困难;优先考虑依赖注入

不复杂但容易忽略

text=ZqhQzanResources