JavaScript设计模式及代码实现——单例模式
2022/8/30 1:23:09
本文主要是介绍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设计模式及代码实现——单例模式的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-15鸿蒙生态设备数量超8亿台
- 2024-05-13TiDB + ES:转转业财系统亿级数据存储优化实践
- 2024-05-09“2024鸿蒙零基础快速实战-仿抖音App开发(ArkTS版)”实战课程已上线
- 2024-05-09聊聊如何通过arthas-tunnel-server来远程管理所有需要arthas监控的应用
- 2024-05-09log4j2这么配就对了
- 2024-05-09nginx修改Content-Type
- 2024-05-09Redis多数据源,看这篇就够了
- 2024-05-09Google Chrome驱动程序 124.0.6367.62(正式版本)去哪下载?
- 2024-05-09有没有大佬知道这种数据应该怎么抓取呀?
- 2024-05-09这种运行结果里的10.100000001,怎么能最快改成10.1?