迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 算法 >

如何在 JavaScript ES6+ 中实现单例模式

作者:迹忆客 最近更新:2023/02/08 浏览次数:

在这篇文章中,我们将向大家展示如何在 JavaScript 中实现单例模式。

如果我们是一名全栈 JavaScript 开发人员,就会知道 JavaScript 是一种功能强大的语言,可以使用它来构建令人惊叹的网站。 另一方面,如果我们仅将 JavaScript 用于前端表单验证和进行 AJAX 调用,那么我们只是触及了它的表面,它能够做的远不止于此。 由于它是一种功能如此丰富的语言,因此有许多框架建立在它之上。

在本文中,我们将讨论一种对面向对象的 JavaScript 有用的编程模式:单例模式。 单例对象仅在应用程序运行时在全局范围内创建一次。 它们用于共享资源或在应用程序的不同部分之间进行协调。


什么是单例模式?

让我们看一下单例模式的定义:

在软件工程中,单例模式是一种将类的实例化限制为一个“单一”实例的软件设计模式。 当只需要一个对象来协调整个系统的动作时,这很有用。

在开发应用程序时,有时需要跨应用程序创建全局对象。 具体来说,我们需要在整个请求的生命周期内只实例化一次的对象。 例如,它可能是希望在整个请求中保持全局的数据库连接对象,因为不需要为每个请求创建多个数据库对象。 在这种情况下,单例模式非常有用,因为它保证只会实例化一个对象的单个副本。


快速浏览:旧版本 JavaScript 中的单例模式

在本节中,我们将快速了解如何在旧版本的 JavaScript 中实现单例模式。

让我们看看下面的例子。

var Singleton = (function () {
    var instance;

    function createInstance() {
        var object = new Object("I was instantiated at: " + new Date().toLocaleString());

        return object;
    }

    return {
        getInstance: function () {
            if (!instance) {
                instance = createInstance();
            }

            return instance;
        }
    };
})();

var instance1 = Singleton.getInstance();
var instance2 = Singleton.getInstance();

console.log(instance1);
console.log(instance2);

在上面的例子中,我们将 Singleton 对象实现为一个闭包,因此它会被立即调用。 它实现了 getInstance 方法,我们可以调用它来实例化一个对象。 在 getInstance 方法中,我们检查实例属性是否已经包含我们要查找的对象,如果存在,我们将不会创建另一个对象。 如果它不包含任何对象,我们将调用 createInstance 方法来实例化一个新对象,然后我们将返回它。 通过这种方式,它可以确保每当我们尝试实例化一个新对象时,只会创建一个对象的副本。

为了演示它,我们两次调用 Singleton.getInstance() 方法来检查它是否真的创建了两个不同的对象。 在控制台中,我们应该能够看到这两个对象是相同的,并且它们都打印相同的日期和时间。

这就是在旧版本的 JavaScript 中实现单例模式的方法。 在下一节中,我们将了解如何在 JavaScript ES6+ 版本中实现它。


ES6+ 中的单例模式

在本节中,我们将了解如何在 JavaScript ES6+ 版本中实现单例模式。 说到 ES6 方式,有几种不同的方法可以用来实现单例模式。

ES6 模块

如果你使用过 ES6 模块,并且你还不知道,那么 ES6 模块默认是单例的。 具体来说,通过结合模块和 const 关键字,我们可以轻松编写单例。

让我们看看下面的 ES6 模块代码。

const currentDateAndTime = new Object("I am instantiated at:" + new Date().toLocaleString());
export default currentDateAndTime;

所以现在,无论何时导入上述 ES6 模块,都可以保证获得相同版本的 currentDateAndTime 对象。 由于 currentDateAndTime 对象的作用域是一个模块,因此可以保证每次在其他文件中包含上述 ES6 模块时,我们都会获得相同的对象。

ES6 类

在本节中,我们将了解如何使用 ES6 类来实现单例模式。

让我们看看下面的例子。

class DBConnection {
  constructor(conString) {
      this.conString = conString
  }

  static getInstance(conString) {
    if (!this.instance) {
      this.instance = new DBConnection(conString);
    }

    return this.instance;
  }
}

let con1 = DBConnection.getInstance('mysqldb1');
let con2 = DBConnection.getInstance('mysqldb2');

//the connections are the same
console.log("con1: "+con1.conString);
console.log("con2: "+con2.conString);

如大家所看到的,我们已经实现了 DBConnection 类,我们可以使用它来实例化应用程序中的数据库连接对象。

为了对此进行测试,我们通过调用 DBConnection 类的 getInstance 方法实例化了两个对象。 然后,我们比较了两个对象,看看它们是否相同。 由于我们使用的是单例模式,它们应该是相同的,并且 console.log 语句将打印 true 以确认它。 我们可以将其称为惰性单例对象,因为对象仅在需要时创建,而不是在初始加载期间创建。

这就是你如何定义一个实现单例模式的类。

带有模块的 ES6 类

在本节中,我们将了解如何使用 ES6 类和模块来实现单例模式。

让我们看看下面的例子。

constructor(conString) {}
  static getInstance(conString) {
    if (!this.instance) {
      this.instance = new DBConnection(conString);
    }
    return this.instance;
  }
}
const dbConObj = DBConnection.getInstance('mysqldb1');
export default dbConObj;

创建作用域为模块的类的实例是实现单例模式的最佳方式。 因此,如果我们正在使用 ES6 模块,这是使用 ES6 类实现单例模式的推荐方法。

这就是如何使用 ES6 类和模块实现单例模式。

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便