前言

在软件开发中,有时我们希望某个类在系统中只存在一个实例,且能够被整个应用程序共享。例如,在一个大型系统中,如果每次访问某个资源都需要创建一个新的实例,不仅会浪费系统资源,还可能导致意想不到的问题。单例模式正是为了解决这个问题而设计的。

特点:

  • 只有一个实例,全局都可以访问该实例
  • 避免重复创建,减少内存占用。

简单版

闭包实现

var SingleTon = (function () {
  var instance;
  function Instance() {}
  return function () {
    if (instance == undefined) {
      instance = new Instance();
    }
    return instance;
  };
})();

var s1 = SingleTon();
var s2 = SingleTon();
console.log(s1 === s2);
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

ES6

class SingleTon {
  constructor() {
    if (SingleTon.instance == undefined) {
      SingleTon.instance = this;
    }
    return SingleTon.instance;
  }
}

const s1 = new SingleTon();
const s2 = new SingleTon();
console.log(s1 === s2);
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

惰性单例

惰性单例(Lazy Singleton)模式是一种创建型设计模式,它延迟对象的创建直到第一次使用该对象时才进行。这种模式可以节省资源,尤其是在对象的创建成本较高或者对象不一定需要被创建的情况下。

var 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;
    },
  };
})();

const s1 = Singleton.getInstance();
const s2 = Singleton.getInstance();
console.log(s1 === s2); // true
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.

适用场景:

  • 需要唯一实例:确保在全局范围内只存在一个实例,并且所有访问该实例的请求都能获得相同的实例。
  • 延迟加载:实例的创建比较耗时,或不一定在程序启动时就需要,可以通过惰性初始化来优化性能。

透明单例

透明单例(Transparent Singleton)是一种变体的单例模式,旨在让单例的使用更加简洁,不需要通过专门的方法来获取实例。使用透明单例时,类的实例化是自动进行的,开发者可以直接像使用普通类一样使用它,而不需要关心是否已经存在实例

代理单例

注意事项:在JavaScript中,单例模式可能不是总是必要的,因为模块机制和全局对象已经提供了一种类似单例的功能。惰性单例模式更适用于那些确实需要控制实例化时机的场景。