单例模式

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

在 JavaScript 开发中,有一些对象只需要一个。比如单击登录按钮,页面会出现登录对话框,并且是唯一的。
无论单击多少次按钮,登录对话框都只会被创建一次,那么这个登录对话框就比较适合用单例模式创建。

1. 单例模式的实现(不透明)

实现思路:通过一个变量标记当前是否已经为某个类创建实例,如果是则下一次获取该类的实例,否则进行新建。

const Singleton = function (name) {
  this.name = name;
};

Singleton.prototype.getName = function () {
  return this.name;
};

Singleton.getInstance = (function (name) {
  let instance = null;

  return function () {
    if (!instance) {
      instance = new Singleton(name);
    }

    return instance;
  };
})();

const singleA = Singleton.getInstance("sven1");
const singleB = Singleton.getInstance("sven2");

console.log(singleA === singleB); // true

弊端:此方法通过 getInstance 可以保证只会创建一个实例,但是无法保证通过 new Singleton
这个方式创建其他的实例,所以意义不大。

2. 透明的单例模式

实现思路:通过必报和自执行匿名函数,可以把 instance 封装起来,不被外界访问得到。

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

  function CreateSingleton(name) {
    this.name = name;
  }

  CreateSingleton.prototype.getName = function () {
    return this.name;
  };

  return function (name) {
    if (!instance) {
      instance = new CreateSingleton(name);
    }

    return instance;
  };
})();

const singleA = new Singleton("sven1");
const singleB = new Singleton("sven2");

console.log(singleA === singleB); // true

弊端:通过匿名函数和闭包创建,增加了程序的复杂度,不易理解。

3. 代理实现单例模式

通过代理类,可以让 Singleton 变为一个普通的函数。

function Singleton(name) {
  this.name = name;
}

Singleton.prototype.getName = function () {
  return this.name;
};

const ProxySingleton = (function () {
  let instance = null;

  return function (name) {
    if (!instance) {
      instance = new Singleton(name);
    }

    return instance;
  };
})();

const singleA = new ProxySingleton("sven1");
const singleB = new ProxySingleton("sven2");

console.log(singleA === singleB); // true

4. 惰性单例模式

惰性单例是指在需要的时候才创建对象实例。

// 将函数作为一个参数传递
const getSingle = function (fn) {
  let result;
  return function () {
    // 通过apply的方式收集参数并执行传入的参数将结果返回
    return result || (result = fn.apply(this, arguments));
  };
};

这种方式最大的优点就是缓存了需要的结果,并且可以在需要的时候去调用,符合封装的单一职责。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。