JavaScript设计模式及代码实现——单例模式
单例模式

1 定义
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
2 应用时机
- 当一个类的实例被频繁使用,如果重复创建这个实例,会无端消耗资源。比如 dialog 弹窗会被全局重复使用
- 业务功能本身决定了全局只能有唯一的实例。比如 redux 管理的数据,只能有唯一的一份
3 应用场景
- 对于前端应用的许多基本组件:比如 dialog、message等等,会被全局频繁使用,就应该维护一个全局唯一的实例,避免重复创建带来不必要的资源消耗。业务组件也同理:比如购物车组件、登录弹窗组件等
- 对于一些通用的工具库,经常会使用单例模式。比如我们通常会创建一个全局唯一的 axios 实例来发起网络请求
- 对于 redux、vuex 等状态管理库,都采用全局唯一的 store 来存储应用状态数据
等等 ……
4 代码实现
4.1 全局变量和命名空间
根据单例模式的定义
// 维护类 A 的唯一实例
class A {}
window.a = new A(); // 或 global.a = new A(); 浏览器用 window
这种方法存在很明显的缺陷,因为同一项目的所有程序员都可以定义全局的变量 a,很容易造成全局污染。
解决办法是设定一个自己的命名空间来和其他人区分
// 比如我设定自己的命名空间 JiMing
window.JiMing = {
a: new A()
}
如果使用 TypeScript ,可以使用关键字 namespace
namespace JiMing {
export const a = new A();
}
4.2 惰性单例
上述实现中,我们直接在全局创建了类 A 的单一实例,无论其是否被使用,这在某些场景会造成资源浪费。有时我们希望在用到的时候再创建实例
如下代码利用立即执行函数和闭包来得到 A 的单例获取函数:getSingletonOfA
class A {}
const getSingletonOfA = (() => {
let instance;
return () => {
return (instance ??= new A());
};
})();
只有在调用getSingletonOfA才会创建 A 的实例,并且会在闭包中将其储存在 instance 中,重复调用getSingletonOfA会获取相同的实例
const a1 = getSingletonOfA();
const a2 = getSingletonOfA();
console.log(a1 === a2); // true
上述方法能够满足单例模式,但是不够通用,改造如下
const createSingletonUtil = (className) => {
let instance;
return () => {
return (instance ??= new className());
};
};
我们封装一个工具函数createSingletonUtil,调用该函数后可以获得任意类的“单例获取函数”
const getSingletonOfA = createSingletonUtil(A);
const a3 = getSingletonOfA();
const a4 = getSingletonOfA();
console.log(a3 === a4); // true
createSingletonUtil 的 TypeScript 实现如下:
class A {}
const createSingletonUtil = <T>(className: new () => T) => {
let instance: T;
return () => {
return (instance ??= new className());
};
};
const getSingletonOfA = createSingletonUtil<A>(A);
const a1 = getSingletonOfA();
const a2 = getSingletonOfA();
console.log(a1 === a2);
当然惰性单例也有缺点,对于某些类,如果创建实例需要较长时间,这时在用到的时候再创建恐怕来不及,可能会产生其他副作用,比如造成页面卡顿。在此场景下,在应用初始化时就创建其实例或许会有更好的用户体验
上述两种方法根据不同的业务场景择一使用即可
公众号【今天也要写bug】(op-bot)提问答疑
JavaScript设计模式及代码实现——单例模式的更多相关文章
- JavaScript设计模式与开发实践 - 单例模式
引言 本文摘自<JavaScript设计模式与开发实践> 在传统开发工程师眼里,单例就是保证一个类只有一个实例,实现的方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返 ...
- JavaScript设计模式(二) - 单例模式
什么是单例模式? 单例模式从字面上的理解是不困难的,js上就是指只有一个对象实例. 为什么需要单例模式? 我们可以将一些成员变量封装在一个单例对象中,每次访问这些变量都只能从这个单例对象进行访问,这样 ...
- JavaScript设计模式样例四 —— 单例模式
单例模式(Singleton Pattern): 定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点. 目的:阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例. 场景: ...
- JavaScript 设计模式及代码实现——代理模式
代理模式 1 定义 为其他对象提供一种代理以控制对这个对象的访问 在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 2 应用举例 2.1 缓 ...
- Javascript设计模式笔记
Javascript是越来越厉害了,一统前后端开发.于是最近把设计模式又看了一遍,顺便做了个笔记,以方便自己和他人共同学习. 笔记连载详见:http://www.meteorcn.net/wordpr ...
- JavaScript设计模式-单例模式、模块模式(转载 学习中。。。。)
(转载地址:http://technicolor.iteye.com/blog/1409656) 之前在<JavaScript小特性-面向对象>里面介绍过JavaScript面向对象的特性 ...
- 《javascript设计模式》读书笔记四(单例模式)
1.单利模式简单介绍 在<设计模式>中单利模式是一种比較简单的模式,定义例如以下: 确保某一个类仅仅有一个实例,并且自行实例化并向整个系统提供这个实例. 在javascript中则将代码组 ...
- 探索Javascript设计模式---单例模式
最近打算系统的学习javascript设计模式,以便自己在开发中遇到问题可以按照设计模式提供的思路进行封装,这样可以提高开发效率并且可以预先规避很多未知的问题. 先从最基本的单例模式开始. 什么是单例 ...
- 再起航,我的学习笔记之JavaScript设计模式10(单例模式)
单例模式 单例模式(Singleton) : 又被称为单体模式,是只允许实例化一次的对象类.一个类有且仅有一个实例,并且自行实例化向整个系统提供. 命名空间 单例模式可能是JavaScript中我们最 ...
随机推荐
- 1.设计模式第一步-《设计模式从头到脚舔一遍-使用C#实现》
更新记录: 完成第一次编辑:2022年4月23日20:29:33. 加入小黄人歌曲:2022年4月23日21:45:36. 1.1 设计模式(Design Pattern)是什么 设计模式是理论.是前 ...
- 2.2.1 用户态、内核态的形成 -《zobolの操作系统学习札记》
内核态的出现,让计算机系统的权力向操作系统高度集中了. 操作系统分出内核态和用户态,就是为了进行不同等级的权限管理, 从而更好的适应多用户多任务并发的工作环境. 用户态和内核态的来源 在早期的单进程单 ...
- Error: $injector:modulerr Module Error
Failed to instantiate module app due to://实例化失败 Error: [$injector:modulerr] http://errors.angularjs. ...
- 排名前三——python 开源 IDE
写在前面的一些P话: Python无处不在 ,似乎它支持从主要网站到桌面实用程序到企业软件的所有功能. Python已经被用来编写流行的软件项目,如dnf / yum,OpenStack,OpenSh ...
- RT-Thread 组件 FinSH 使用时遇到的问题
一.FinSH 的移植与使用问题 FinSH组件输入无反应的问题 现象:当打开 finsh 组件后,控制台会打相应的信息,如下图说是: \ | / - RT - Thread Operating Sy ...
- Linux 更改家目录下的目录为英文
export LANG=en_US xdg-user-dirs-gtk-update
- 4-4 Spring Test
Spring Test Ⅰ.主要解决的问题 使用SpringTest前 手动加载Sping配置 手动从Spring容器中获取对象 使用SpringTest后 只需要通过注解指定Spring配置类 在S ...
- 我为 Netty 贡献源码 | 且看 Netty 如何应对 TCP 连接的正常关闭,异常关闭,半关闭场景
欢迎关注公众号:bin的技术小屋,本文图片加载不出来的话可查看公众号原文 本系列Netty源码解析文章基于 4.1.56.Final版本 写在前面..... 本文是笔者肉眼盯 Bug 系列的第三弹,前 ...
- 【万字长文】使用 LSM-Tree 思想基于.Net 6.0 C# 实现 KV 数据库(案例版)
文章有点长,耐心看完应该可以懂实际原理到底是啥子. 这是一个KV数据库的C#实现,目前用.NET 6.0实现的,目前算是属于雏形,骨架都已经完备,毕竟刚完工不到一星期. 当然,这个其实也算是NoSQL ...
- Linux系统上传公钥不生效问题
Authentication refused: bad ownership or modes for file /home/yanbo.xu/.ssh/authorized_keys 原因: sshd ...