当前位置: 首页 > Web前端 > HTML5

JS设计模式解析:单例模式

时间:2023-04-05 21:19:50 HTML5

好的设计模式可以显着提高代码可读性,降低复杂度和维护成本。作者打算在几篇文章中谈谈常见或实用的设计模式。今天先从最简单的开始:单例模式。本文中的示例代码将使用ES6语法来简化不必要的细节。单例模式(Singleton)是一种创建型设计模式,它限制我们只能创建单个对象或某个类的单个实例。通常,此模式用于控制整个应用程序的状态。在日常开发中,我们遇到的单例模式可能包括:Vuex中的Store、Vue的根实例、任意导出单个对象的ES6模块等。最简单的字面写法的单例其实是这样的:constcat={name:'mi',age:4}懂const语法的人都知道这只猫不能被重新赋值,但是它包含的属性其实是可变的。如果你想要一个不可变的单例对象:constcat={name:'mi',age:4}Object.freeze(cat);以至于不能在这只猫上添加或修改任何属性,它就变成了Frozen喵~如果用在模块中,上面的写法不会污染全局作用域,但是直接生成一个固定的对象就缺少了一些灵活性。常用的写法相对来说,使用类或者工厂方法来实现单例是比较常见的。假设我们有一个名为Logger的类,它具有与Console相同的API。单例类的单例写法很常见,如果我们要这样使用的话:constlogger=newLogger();logger.log('msg');//这里写了大约1000行代码constlogger2=newLogger();logger.log('newmsg');logger===logger2;//true表示即使Logger多次被new,它返回的是同一个实例。直接看最实际的实现:classLogger{constructor(){if(!Logger._singleton){Logger._singleton=this;}返回Logger._singleton;}log(...args){console.log(...args);}}导出默认记录器;上面的方法在构造函数中保存了单例对象,这样无论创建多少次新的Logger,都会返回同一个Logger实例。这里有一个细节需要注意,就是如果new关键字后面的构造函数显式返回了一个对象,new表达式就会返回这个对象。详情请参考《你不知道的 JavaScript (上卷)》新装订的相关章节。工厂单例如果你不喜欢使用new关键字,你可以使用工厂方法返回一个单例对象。letlogger=nullclassLogger{log(...args){console.log(...args);}}functioncreateLogger(){if(!logger){logger=newLogger();}returnlogger;}exportdefaultcreateLogger;上面的代码相当于在模块内部缓存了logger实例,然后导出一个工厂方法。这种写法在模块化代码中比较常见,工厂方法也可以接收参数来初始化单例对象。今天的内容比较通俗易懂,单例的写法也是笔者常用的写法。下一篇我们会详细说说工厂模式的应用~参考内容《JavaScript 设计模式》《JavaScript 面向对象编程指南》《你不知道的 JavaScript (上卷)》WorkingwithSingletonsinJavaScript