JavaScript 中的单例模式(Singleton Pattern)

JavaScript 中的单例模式(Singleton Pattern)

单例模式是一种创建型设计模式,确保一个类只有一个实例,并提供全局访问点。在 JavaScript 中,它常用于管理全局状态、配置对象、缓存等场景。


核心目标

  • 确保类只有一个实例。
  • 提供全局访问点(如 Singleton.getInstance())。

实现方式

以下是几种常见的实现方案:

1. 闭包 + IIFE(经典实现)
javascript 复制代码
const Singleton = (() => {
  let instance; // 私有变量,存储唯一实例

  function createInstance() {
    // 私有构造函数逻辑
    const object = new Object("I am the instance");
    return object;
  }

  return {
    getInstance: () => {
      if (!instance) {
        instance = createInstance(); // 延迟初始化
      }
      return instance;
    },
  };
})();

// 使用
const instance1 = Singleton.getInstance();
const instance2 = Singleton.getInstance();
console.log(instance1 === instance2); // true
2. ES6 Class(静态属性版)
javascript 复制代码
class Singleton {
  static instance; // 静态属性存储实例

  constructor() {
    if (Singleton.instance) {
      return Singleton.instance; // 阻止重复创建
    }
    Singleton.instance = this;
    // 初始化逻辑
    this.data = "Singleton Data";
  }

  // 可选:静态方法获取实例
  static getInstance() {
    if (!this.instance) {
      this.instance = new Singleton();
    }
    return this.instance;
  }
}

// 使用
const obj1 = new Singleton();
const obj2 = new Singleton();
console.log(obj1 === obj2); // true

// 或通过静态方法
const obj3 = Singleton.getInstance();
console.log(obj1 === obj3); // true
3. 模块化(现代推荐方案)

利用 ES6 模块的天然单例特性(模块仅执行一次):

javascript 复制代码
// singleton.js
let instance;

export default class Singleton {
  constructor() {
    if (instance) {
      return instance;
    }
    instance = this;
    this.state = { count: 0 };
  }

  increment() {
    this.state.count++;
  }
}

// 其他文件导入时,总是获得同一个实例
import Singleton from './singleton.js';
const singleton = new Singleton();

关键特性

特性 说明
唯一实例 通过闭包/静态属性/模块缓存确保实例唯一性。
延迟初始化 实例在首次访问时创建(非必须,但常见)。
全局访问 通过 getInstance() 或模块导入全局访问。
阻止直接实例化 构造函数内检查实例是否存在,避免 new 重复创建。

使用场景

  • 全局状态管理:如 Redux Store、Vuex Store。
  • 配置对象:应用配置(API 密钥、环境变量)。
  • 缓存系统:共享缓存池。
  • 日志工具:全局日志实例。
  • 数据库连接池:避免重复创建连接。

注意事项

  1. 测试困难:单例的全局状态可能影响测试隔离性(可通过依赖注入解决)。
  2. 过度使用风险:滥用会导致代码耦合度高(违背单一职责原则)。
  3. 多线程问题:JavaScript 是单线程,无需考虑线程安全(Node.js 的 Cluster 模块除外)。

与全局变量的区别

单例模式 全局变量
惰性初始化(按需创建) 启动时立即初始化
封装实现细节 暴露所有属性/方法
可扩展性(可继承、子类化) 难以扩展

总结

单例模式在 JavaScript 中通过 闭包静态属性模块化 实现,是管理全局资源的有效工具。使用时需权衡其便利性与潜在的设计耦合问题。现代前端框架(如 React Context、Vue Provide/Inject)提供了更优雅的状态共享方案,但单例模式在基础库和工具中仍有重要地位。

相关推荐
南玖i2 分钟前
vue3 通过 Vue3DraggableResizable实现拖拽弹窗,可修改大小
前端·javascript·vue.js
YAY_tyy8 分钟前
Three.js 开发实战教程(五):外部 3D 模型加载与优化实战
前端·javascript·3d·three.js
Zuckjet_3 小时前
开启 3D 之旅 - 你的第一个 WebGL 三角形
前端·javascript·3d·webgl
bitbitDown5 小时前
四年前端分享给你的高效开发工具库
前端·javascript·vue.js
YAY_tyy5 小时前
【JavaScript 性能优化实战】第六篇:性能监控与自动化优化
javascript·性能优化·自动化
gnip6 小时前
实现AI对话光标跟随效果
前端·javascript
闭着眼睛学算法7 小时前
【华为OD机考正在更新】2025年双机位A卷真题【完全原创题解 | 详细考点分类 | 不断更新题目 | 六种主流语言Py+Java+Cpp+C+Js+Go】
java·c语言·javascript·c++·python·算法·华为od
烛阴7 小时前
【TS 设计模式完全指南】构建你的专属“通知中心”:深入观察者模式
javascript·设计模式·typescript
lumi.7 小时前
Vue.js 从入门到实践1:环境搭建、数据绑定与条件渲染
前端·javascript·vue.js
二十雨辰7 小时前
vue核心原理实现
前端·javascript·vue.js