文档章节

JS设计模式之单例模式

o
 osc_y8yehimr
发布于 2019/03/20 16:27
字数 759
阅读 10
收藏 0

精选30+云产品,助力企业轻松上云!>>>

单例模式

单例模式的定义是:保证一个类只有一个实例,并提供一个访问它的全局访问点。比如说购物车,在一个商城中,我们只需要一个购物车,购物车在整个商城中是唯一的,不需要多次创建,即使多次点击购物车按钮,也不会生成多个购物车。

闭包预警:有对闭包不明白的同学,可以看这里

让我们实现一个单例模式吧

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

Singleton.getInstance = (function () {
  var instance = null;
  return function (name) {
    if (!instance) {
      instance = new Singleton(name);
    }
    return instance;
  }
})()

var single1 = Singleton.getInstance('张三');
var single2 = Singleton.getInstance('李四');

console.log(single1 === single2); // 输出true

我们主要看一下Singleton.getInstance方法,其中将变量instance作为一个标志,来确认是否创建过Singleton对象。如果没有就创建一个Singleton对象,反之则返回之前创建过的对象。

这样我们创建Singleton对象的时候,就得使用Singleton.getInstance方法,而不是使用new关键字来创建对象。如果想使用new关键字的话,可以这样写。

使用代理类来实现单例模式

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

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

var single1 = new ProxySingleton('张三');
var single2 = new ProxySingleton('李四');

console.log(single1 === single2); // 输出true

我们将管理单例的逻辑放入ProxySingleton这个代理类中,从而使Singleton变成一个普通的类或者构造函数。这样我们就可以通过new关键字来创建对象。

创建对象和管理单例逻辑职责分离

var createObj = function(name, age) {
  return {
    name: name,
    age: age
  }
}

var getSingle = function(fn) {
  var instance = null;
  return function () {
    return instance || (instance = fn.apply(this, arguments));
  }
}

var CreateFn = getSingle(createObj);

var obj1 = CreateFn('张三', 18);
var obj2 = CreateFn('李四', 19);

console.log(obj1 === obj2); // 输出true

这里createObj方法负责创建对象和处理内部逻辑,getSingle方法只负责管理单例的逻辑。这样在创建各种单例对象的情况下,使用更加灵活。也符合单一职责的开发原则。

单例模式的使用场景

单例模式的使用场景非常广泛,这里举几个🌰。

jQuery只有一个$

if (window.$ != null) {
  return window.$
} else {
  // 初始化...
}

模拟一个登录框

var LoginForm = function() {
  this.state = 'hide';
}

LoginForm.prototype.show = function () {
  if (this.state === 'show') {
    alert('登录框已经显示');
    return;
  }
  this.state = 'show';
  console.log('登录框显示成功');
}

LoginForm.prototype.hide = function () {
  if (this.state === 'hide') {
    alert('登录框已经隐藏');
    return;
  }
  this.state = 'hide';
  console.log('登录框隐藏成功');
}

// 这里也可以直接用代理类
LoginForm.getInstance = (function () {
  var instance = null;
  return function () {
    if (!instance) {
      instance = new LoginForm();
    }
    return instance;
  }
})();

var login1 = LoginForm.getInstance();
login1.show();
var login2 = LoginForm.getInstance();
login2.hide();

console.log(login1 === login2); // 输出true

其他场景

  • 购物车
  • vuex和redux的store

这里就不给出代码示例了。

惰性单例

这里确实很有必要提到惰性单例。惰性单例就是在需要的时候才创建对象实例。

比如这个例子模拟一个登录框,想要实现通用的惰性单例可以看这个通用惰性单例实现

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
0_JavaScript简介、Javascript课程大纲

JavaScript简介 javascript诞生于1995年,当时它的主要目的就是处理以前由服务器语言负责的一些输入验证操作。在javascript问世之前,必须把表单里的数据发送到服务器才能确定用户是否没有填...

1217528969
2015/02/26
75
0
js设计模式-观察者模式

定义: 观察者模式又叫发布订阅模式,它定义了对象间的一种一对多的依赖关系。观察者模式让两个对象松耦合地联系在一起,虽然不太清楚彼此的细节,但这不影响他们之间的互相通信。 思路 定义...

osc_9g4x7r4s
2019/02/24
5
0
《深入理解JavaScript系列》

《深入理解JavaScript系列》系列技术文章整理收藏 深入理解JavaScript系列来自汤姆大叔的整理贴,原文地址http://www.cnblogs.com/TomXu/archive/2011/12/15/2288411.html 此处收藏供JavaScr...

汐蓝-空
2015/06/23
111
0
你需要了解的23种JavaScript设计模式

为什么要学习设计模式? 在许多访谈中,你可能会遇到很多面向对象编程中的接口,抽象类,代理和以及其他与设计模式相关的问题。 一旦了解了设计模式,它会让你轻松应对任何访谈,并可以在你的...

java高级架构牛人
2018/06/02
18
0
JavaScript设计模式之观察者模式

一、什么是观察者模式 观察者模式又叫做发布—订阅模式,是我们最常用的设计模式之一。它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知和...

osc_6ogjsu3t
2019/03/04
2
0

没有更多内容

加载失败,请刷新页面

加载更多

Linux系统检查用户账户到期时间

如果你在 Linux 上启用了密码策略。密码必须在到期前进行更改,并且登录到系统时会收到通知。如果你很少使用自己的帐户,那么可能由于密码过期而被锁定。在许多情况下,这可能会在无需密码登...

老孟的Linux私房菜
26分钟前
13
0
关于南京哪里有开餐饮费发票?

关于南京哪里有开餐饮费发票?聚焦餐饮行业,谈话〖18 7一電一7 5 3 8一徴一3331〗研究院昨发布数据显示,今年上半年,全国餐饮行业招聘需求增长46.18%,平均月薪6387元.随着餐饮行业的快速...

点击fojewio
59分钟前
7
0
android studio 4.0 打开DDMS

1、先找到AndroidStudio配置的SDK路径; 2、在SDK的/tools/路径下有个monitor.bat 的批处理文件; 3、鼠标连续点击两下monitor.bat这个批处理文件,在屏幕上会打开一个类似CMD的命令行中输入...

chenhongjiang
今天
10
0
如何在Android中使用SharedPreferences来存储,获取和编辑值

问题: Closed . 已关闭 。 This question needs to be more focused. 这个问题需要更加集中。 It is not currently accepting answers. 它当前不接受答案。 Learn more . 了解更多 。 Want...

fyin1314
今天
6
0
【JDK1.8】LinkedList源码分析

LinkedList的特性 LinkedList内部使用双向链表作为存储结构,LinkedList可以理解为链表的扩展对象,封装了常用的和非常用的操作链表的方法。以及在通过索引获取元素时的简单优化,通常Linke...

XuePeng77
今天
36
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部