单例模式

2024/03/22 JavaScript 共 1383 字,约 4 分钟

单例模式

保证一个类仅有一个实例,并提供一个访问它的全局访问点。比如window对象,全局缓存,全局状态管理,全局弹窗等等

原理:

用一个变量来标志当前是否已经为某个类创建过对象,如果是,则在下一次获取该类的实例时,直接返回之前创建的对象

比如

class SingInstance {
  instance = null;
  static getInstance() {
    if (!this.instance) {
      this.instance = new SingInstance();
    }
    return this.instance;
  }
  getName(name) {
    return name;
  }
}
const instance1 = SingInstance.getInstance();
const instance2 = SingInstance.getInstance();
console.log(instance1 === instance2); // true

我们通过SingInstance.getInstance来获取SingInstance类的唯一对象,这种方式相对简单,但有一个问题,就是增加了这个类的“不透明性”, SingInstance类的使用者必须知道这是一个单例类,跟以往通过new XXX的方式来获取对象不同,这里偏要使用SingInstance.getInstance来获取对象

改进,可以使用代理模式,将SingInstance类的实例化和管理放到代理类中,SingInstance类只负责自己的业务逻辑,代理类负责管理SingInstance类的实例化和管理(代理+匿名函数)

class SingInstance {
  getName() {
    return name;
  }
}

const SingInstanceProxy = (function() {
  let instance = null;
  return function() {
    if (!instance) {
      instance = new SingInstance();
    }
    return instance;
  }
})();

通过引入代理类的方式,我们同样完成了一个单例模式的编写,跟之前不同的是,现在我们把负责管理单例的逻辑移到了代理类SingInstanceProxy中。这样一来,SingInstance就变成了一个普通的类,它跟SingInstanceProxy组合起来可以达到单例模式的效果。

如果只有简单的方法请求,那就可以简单处理,直接给一个全局变量

class SingInstance {
   instance= null;
   async getName() {
    if (this.instance === null) {
      // 处理逻辑
    }
    return this.instance;
  }
}
let counter1 = new Counter(5);
for(letiofcounter1){
  if(i>2){
    break;
  }
  console.log(i);
}
//1
//2
//Exitingearly
let counter2 = new Counter(5);
try {
  for (let i of counter2) {
    if (i > 2) {
      throw'err';
    }
    console.log(i);
  }
} catch(e) {}
// 1
// 2
//Exitingearly
let counter3 = new Counter(5);
let[a, b]=counter3;
//Exitingearly

在技术的历史长河中,虽然我们素未谋面,却已相识已久,很微妙也很知足。互联网让世界变得更小,你我之间更近。

在逝去的青葱岁月中,虽然我们未曾相遇,却共同经历着一样的情愫。谁的青春不曾迷茫或焦虑亦是无奈,谁不曾年少过

在未来的日子里,让我们共享好的文章,共同学习进步。有不错的文章记得分享给我,我不会写好的文章,所以我只能做一个搬运工

我叫 sunseekers(张敏) ,千千万万个张敏与你同在,18年电子商务专业毕业,毕业后在前端搬砖

如果喜欢我的话,恰巧我也喜欢你的话,让我们手拉手,肩并肩共同前行,相互学习,互相鼓励

文档信息

Search

    Table of Contents