Skip to content

单例模式

单例模式的 JavaScript 实现

在 JavaScript 中,单例模式可以通过多种方式来实现。这里提供一种现代且线程安全(在 JavaScript 环境中,由于其单线程特性,“线程安全”更多是指避免并发问题)的实现方式。

现代 JavaScript 实现

考虑到 ES6 及之后的语法改进,我们可以使用类和闭包来创建一个更加模块化和清晰的单例模式实现:

javascript
class Singleton {
  constructor(name) {
    if (!Singleton.instance) {
      this.name = name;
      Singleton.instance = this;
    }
    return Singleton.instance;
  }

  getName() {
    return this.name;
  }
}

// 确保只有一个实例被创建
const instance1 = new Singleton("SingletonInstance");
const instance2 = new Singleton("AnotherInstance");

console.log(instance1 === instance2); // 输出: true
console.log(instance1.getName()); // 输出: SingletonInstance
console.log(instance2.getName()); // 输出: SingletonInstance

在这个例子中,Singleton 类的构造函数首先检查 Singleton.instance 是否已经被定义。如果没有,则将当前实例赋值给 Singleton.instance 并初始化属性;如果已经存在,则直接返回现有的实例。这种方式确保了无论多少次尝试创建新的 Singleton 实例,最终得到的都是同一个实例。

使用闭包实现

另外,也可以通过闭包来实现单例模式,这种方式更加灵活,尤其是在需要延迟初始化的情况下:

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

  function createInstance() {
    const object = new Object("I am the instance");
    return object;
  }

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

function useSingleton() {
  const instance1 = Singleton.getInstance();
  const instance2 = Singleton.getInstance();

  console.log(instance1 === instance2); // 输出: true
}

useSingleton();

这里,Singleton 是一个立即执行函数表达式(IIFE),它内部包含了一个私有的 instance 变量和一个 createInstance 函数用于创建实例。getInstance 方法用来检查是否已经存在一个实例,如果不存在,则创建一个新的;如果已存在,则返回现有的实例。

应用场景

  • 状态管理:如 Redux 或 Vuex 这样的状态管理库利用单例模式来维护整个应用程序的状态。
  • 共享资源:例如数据库连接池、配置设置等,通过单例模式可以确保这些资源在整个应用程序中只被初始化一次。
  • 日志记录:为了确保所有的日志消息都由同一个对象处理,可以使用单例模式实现日志记录器。

总之,单例模式是一种简单但非常强大的设计模式,在正确使用的场合下能够极大提升代码的效率和可维护性。然而,也需要注意不要过度使用,以免增加代码的复杂性和耦合度。

Released under the MIT License.