JavaScript 单例模式实现

单例模式的概念、应用场景和两种实现方式

问题

什么是单例模式,如何在 JavaScript 中实现?

解答

什么是单例模式

单例模式保证一个类只有一个实例,并提供一个全局访问点。

应用场景

单例模式适用于需要全局唯一实例的场景:

  • 网站计数器:需要统一计数,避免数据不同步
  • 日志系统:统一管理日志输出和追加
  • 线程池:集中管理和控制线程资源
  • 任务管理器:系统中只能打开一个实例
  • 回收站:整个系统只维护一个回收站实例

实现方式

饿汉式

类初始化时立即创建实例,线程安全,调用效率高。

class Singleton {
  static instance = new Singleton();
  
  constructor() {
    if (Singleton.instance) {
      return Singleton.instance;
    }
  }
  
  static getInstance() {
    return Singleton.instance;
  }
}

const instance1 = Singleton.getInstance();
const instance2 = Singleton.getInstance();
console.log(instance1 === instance2); // true

懒汉式

类初始化时不创建实例,首次使用时才创建,具备懒加载功能。

class Singleton {
  static instance = null;
  
  constructor() {
    if (Singleton.instance) {
      return Singleton.instance;
    }
    Singleton.instance = this;
  }
  
  static getInstance() {
    if (!Singleton.instance) {
      Singleton.instance = new Singleton();
    }
    return Singleton.instance;
  }
}

const instance1 = Singleton.getInstance();
const instance2 = Singleton.getInstance();
console.log(instance1 === instance2); // true

优缺点

优点:

  • 内存中只存在一个实例,节约系统资源
  • 提供对唯一实例的受控访问
  • 避免对共享资源的多重占用
  • 频繁创建销毁对象时可提高性能

缺点:

  • 不适用于需要频繁变化状态的对象
  • 没有抽象层,扩展困难
  • 职责过重,一定程度违背单一职责原则
  • 滥用可能导致连接池溢出等问题
  • 长时间不使用可能被垃圾回收,导致状态丢失

关键点

  • 单例模式确保类只有一个实例,通过静态方法提供全局访问点
  • 饿汉式在类加载时创建实例,线程安全但可能浪费资源
  • 懒汉式在首次使用时创建实例,节省资源但需注意线程安全
  • 适用于全局唯一资源管理场景,如日志、线程池、配置对象等
  • 避免滥用,不适合需要多实例或状态频繁变化的场景