菜鸟-创作你的创作

前端(JavaScript)中单例模式的实现与应用实例

下面给你一份 《前端(JavaScript)中单例模式的实现与应用实例》(2025 最新版),涵盖核心实现方式、ESModule 特性、实际应用场景和完整代码示例,非常适合用于项目、学习或写文章。


🚀 前端(JavaScript)中的单例模式实现与应用实例(2025 最全指南)

单例模式(Singleton):
保证一个类在全局只能有一个实例,并且可以全局访问。

JavaScript 中单例模式尤其常用,因为浏览器环境本身就是天然全局共享的。


⭐ 一、为什么 JS 中需要单例模式?

前端常见需要保证“全局只有一个实例”的场景:

场景说明
全局状态管理如用户信息、权限、配置
全局事件总线 EventBus避免多个实例导致事件丢失
WebSocket 连接整个应用只能有一个连接
弹窗组件(Dialog / Modal)避免多次渲染
缓存管理器防止重复请求接口
配置中心 Config全局统一配置入口

⭐ 二、最常用的 5 种单例实现方式(含最佳实践)


基于闭包的单例(经典写法)

const Singleton = (function () {
  let instance;

  function createInstance() {
    return { name: "singleton instance" };
  }

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

const a = Singleton.getInstance();
const b = Singleton.getInstance();

console.log(a === b); // true

优点:简单、独立,不依赖外部结构
缺点:无法与 ESModule 相结合


基于类 + 静态属性的单例模式(主流推荐)

class Store {
  static instance = null;

  constructor() {
    if (Store.instance) return Store.instance;
    this.data = {};
    Store.instance = this;
  }
}

const s1 = new Store();
const s2 = new Store();

console.log(s1 === s2); // true

优点:


使用 ESModule 的天然单例(最推荐)

ESModule 在浏览器 / Node 中天然只会加载一次。

⚡ 一个模块就是一个单例!

// store.js
export const store = {
  user: null,
  token: null
};

// app.js
import { store } from "./store.js";
store.user = { name: "阿杰" };

在其他组件中:

import { store } from "./store.js";
console.log(store.user); // 永远是同一个对象

优点:
✔ 最干净
✔ 无需额外代码保证单例
✔ 天然缓存(只执行一次)
✔ Vue / React 项目通用

现代前端优先推荐:使用 ESModule 实现单例!


使用 Symbol + 全局注册表(解决多版本冲突)

用于避免多个 bundle 注入不同版本的实例,如微前端场景。

const KEY = Symbol.for("global.singleton");

if (!globalThis[KEY]) {
  globalThis[KEY] = { count: 0 };
}

export default globalThis[KEY];

任何地方导入都获得同一个对象。


立即执行函数 + WeakMap(私有化单例)

用于隐藏实现细节,不能被外部随意修改。

const Singleton = (function () {
  const privateMap = new WeakMap();

  return class {
    constructor() {
      if (!privateMap.has(Singleton)) {
        privateMap.set(Singleton, this);
      }
      return privateMap.get(Singleton);
    }
  };
})();

const s1 = new Singleton();
const s2 = new Singleton();

console.log(s1 === s2); // true


⭐ 三、前端实际应用场景示例(超级实用)


1. WebSocket 单例(最常见)

class WS {
  static instance = null;

  constructor(url) {
    if (WS.instance) return WS.instance;
    this.ws = new WebSocket(url);
    WS.instance = this;
  }
}

export default new WS("wss://server.com");

避免多开 WebSocket 连接。


2. 全局事件总线(EventBus)单例

class EventBus {
  static instance;

  constructor() {
    if (EventBus.instance) return EventBus.instance;
    this.events = {};
    EventBus.instance = this;
  }

  on(name, fn) {
    (this.events[name] ||= []).push(fn);
  }

  emit(name, ...args) {
    (this.events[name] || []).forEach(fn => fn(...args));
  }
}

export default new EventBus();


3. 请求缓存器(防止重复请求)

class Cache {
  static instance;
  constructor() {
    if (Cache.instance) return Cache.instance;
    this.map = new Map();
    Cache.instance = this;
  }

  async fetch(url) {
    if (this.map.has(url)) return this.map.get(url);
    const data = await fetch(url).then(r => r.json());
    this.map.set(url, data);
    return data;
  }
}

export const cache = new Cache();


4. 全局配置中心 Config

export const config = {
  api: "/api",
  version: "1.0.0",
};

ESM 天然单例。


5. UI 弹窗(Modal)单例

避免重复渲染多个弹窗。

class ModalManager {
  static instance;

  constructor() {
    if (ModalManager.instance) return ModalManager.instance;
    this.visible = false;
    ModalManager.instance = this;
  }

  show() { this.visible = true; }
  hide() { this.visible = false; }
}

export default new ModalManager();


⭐ 四、最佳实践(2025 版本)

使用场景推荐单例实现方式
Vue/React 项目ESModule 单例(最干净)
工具库 Class类静态属性单例
微前端、跨包共享Symbol.for + globalThis
高性能动画、游戏场景IIFE + 对象池
私有化、安全性要求高WeakMap 私有化

⭐ 五、总结(可作为文章结尾)

JavaScript 实现单例模式有多种方式,但 2025 年最推荐:

优先使用 ESModule,因为加载一次、全局共享、最符合现代前端架构。
其他方式根据需求补充使用即可。

退出移动版