介绍
singleton 是最知名的设计模式之一. 有时你只需要一个类的实例,而不是更多。 这个类可以是某种资源管理器或某种全球价值观。
在本文中,您将看看什么是Singletons以及如何最好地在JavaScript中实现它们。
前提条件
要成功完成本教程,您将需要以下内容:
- 对 JavaScript 编码的了解. 如果您需要进一步拓展您在该领域的知识,请参阅此 JavaScript 系列。
- 了解如何在 JavaScript 中工作的类。
了解独角兽
Singletons 用于创建一个类的实例,如果它不存在,或者返回现有类的引用,这意味着 singletons 是在应用程序在全球范围内运行时创建一次。
根据这个定义,singletons 看起来非常类似于全球变量. 你可能会想知道为什么 singletons 应该被用来编码具有全球变量的语言. 有几件事使 singletons 与全球变量不同:
- 全球变量是语法范围的,而单个变量不是。这意味着如果在一个编程块中有另一个与全球变量相同的名称的变量,那么第一个参考将得到优先权。
即使在支持全球变量的语言中,singletons 也可能非常有用. 有些情况下,singletons 是有用的. 一些 singletons 应用程序是日志对象或配置设置类。
单身声明
有几种方式来声明一个单曲. 这是你可能看到的一个格式:
1var SingletonInstance = {
2 method1: function () { ... }
3 method2: function () { ... }
4};
这个 singleton 会像这样登录到控制台:
1console.log(SingletonInstance.method1());
2console.log(SingletonInstance.method2());
重要的是要记住,这不是宣布单曲的最佳方式,另一种方法是使用一个工厂类来创建单曲一次。
1var SingletonFactory = (function(){
2 function SingletonClass() {
3 // ...
4 }
5
6 var instance;
7
8 return {
9 getInstance: function(){
10 if (!instance) {
11 instance = new SingletonClass();
12 delete instance.constructor;
13 }
14 return instance;
15 }
16 };
17})();
这是一个更好的替代方案,因为类的定义是私有的,而构建器在创建第一个实例后被删除,这将防止程序中创建重复的单字符号。
这个方法实现了 ES6 类和 Object.freeze() 方法的组合:
1[label script.js]
2class Singleton {
3 constructor() {
4 // ...
5 }
6
7 method1() {
8 // ...
9 }
10
11 method2() {
12 // ...
13 }
14}
15
16const singletonInstance = new Singleton();
17
18Object.freeze(singletonInstance);
「Object.freeze()」方法可防止对一个对象的属性和值进行更改,因此将「Object.freeze()」应用到「singletonInstance」意味着您将无法在代码中更改其属性或值。
您可以进一步写入这个单字符号作为一个模块,并使用 ES6 导出功能导出:
1[label script.js]
2export default singletonInstance;
然后,这个 singleton 可以通过导入到单独的文件中使用:
1[label otherFile.js]
2import mySingleton from './script.js';
3
4mySingleton.method1();
使用这些三种方法来创建单字符,选择哪种方法最适合您的特定用例,允许高可读性。
结论
在您的 JavaScript 代码中并不总是需要使用 singletons. 在不会影响应用程序的状态的情况下使用 singletons. 这种限制严重限制了它们在大型应用程序中的使用。
使用此基本设计模式在您的工具包中,您可能想探索 JavaScript 中的工厂模式。 如果您有兴趣了解更多关于状态管理的文章,请查看这些文章中的 React with Redux 中的状态管理和 React 与头盔的状态管理。