How to implement the singleton pattern in JavaScript ES6+
In this article, we will show you how to implement the singleton pattern in JavaScript.
If we are a full-stack JavaScript developer, we know that JavaScript is a powerful language and we can build amazing websites with it. On the other hand, if we only use JavaScript for front-end form validation and making AJAX calls, then we have only scratched the surface of it and it is capable of doing much more than that. Since it is such a feature-rich language, there are many frameworks built on top of it.
In this article, we'll discuss a programming pattern that's useful for object-oriented JavaScript: the singleton pattern. Singleton objects are created only once in the global scope when the application runs. They're used to share resources or coordinate between different parts of an application.
What is the singleton pattern?
Let's look at the definition of the singleton pattern:
In software engineering, the singleton pattern is a software design pattern that restricts the instantiation of a class to a "single" instance. This is useful when only one object is needed to coordinate the actions of the entire system.
When developing an application, sometimes you need to create global objects across the application. Specifically, we need objects that are instantiated only once throughout the lifecycle of a request. For example, it might be a database connection object that you want to remain global across requests because you don't need to create multiple database objects for each request. In this case, the singleton pattern is very useful because it guarantees that only a single copy of an object will be instantiated.
A quick look at the singleton pattern in older versions of JavaScript
In this section, we'll take a quick look at how to implement the singleton pattern in older versions of JavaScript.
Let's look at the following example.
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);
In the example above, we implemented the Singleton object as a closure, so it will be called immediately. It implements getInstance
the method, which we can call to instantiate an object. In getInstance
the method, we check if the instance attribute already contains the object we are looking for, and if it does, we will not create another object. If it does not contain any object, we will call createInstance
the method to instantiate a new object, and then we will return it. In this way, it ensures that whenever we try to instantiate a new object, only a copy of the object will be created.
To demonstrate it, we call Singleton.getInstance()
the method twice to check if it really creates two different objects. In the console, we should be able to see that the two objects are identical and that they both print the same date and time.
This is how you implement the singleton pattern in older versions of JavaScript. In the next section, we will see how to implement it in JavaScript ES6+ versions.
Singleton Pattern in ES6+
In this section, we will see how to implement the singleton pattern in JavaScript ES6+ version. Speaking of ES6 way, there are several different ways to implement the singleton pattern.
ES6 modules
If you've used ES6 modules, and you didn't know it, ES6 modules are singletons by default. Specifically, by combining modules and const
the keyword, we can easily write singletons.
Let's look at the following ES6 module code.
const currentDateAndTime = new Object("I am instantiated at:" + new Date().toLocaleString());
export default currentDateAndTime;
So now, whenever we import the above ES6 module, we are guaranteed to get the same version of currentDateAndTime
the object. Since currentDateAndTime
the object is scoped to a module, we are guaranteed to get the same object every time we include the above ES6 module in other files.
ES6 Classes
In this section, we will see how to implement the singleton pattern using ES6 classes.
Let's look at the following example.
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);
As you can see, we have implemented DBConnection
the class, which we can use to instantiate database connection objects in our application.
To test this, we instantiated two objects by calling the method DBConnection
of the class . We then compared the two objects to see if they are identical. Since we are using the singleton pattern, they should be identical, and the statement will print true to confirm it. We can call this a lazy singleton object because the object is only created when needed, not during the initial load.getInstance
console.log
This is how you define a class that implements the singleton pattern.
ES6 Classes with Modules
In this section, we will see how to implement the singleton pattern using ES6 classes and modules.
Let's look at the following example.
constructor(conString) {}
static getInstance(conString) {
if (!this.instance) {
this.instance = new DBConnection(conString);
}
return this.instance;
}
}
const dbConObj = DBConnection.getInstance('mysqldb1');
export default dbConObj;
Creating an instance of a module-scoped class is the best way to implement the singleton pattern. So if we are using ES6 modules, this is the recommended way to implement the singleton pattern using ES6 classes.
This is how to implement the singleton pattern using ES6 classes and modules.
For reprinting, please send an email to 1244347461@qq.com for approval. After obtaining the author's consent, kindly include the source as a link.
Related Articles
How to use the Adapter design pattern in Java
Publish Date:2025/03/19 Views:76 Category:ALGORITHM
-
The Adapter design pattern in Java , also known as the Wrapper pattern, is another very useful GOF pattern that helps bridge the gap between two classes in Java. According to the Gang of Four pattern list, Adapter is a structural pattern, m
Java Decorator Design Pattern Example
Publish Date:2025/03/19 Views:115 Category:ALGORITHM
-
Hello everyone, if you want to learn about Decorator Design Pattern in Java , then you have come to the right place. As design patterns are very important while building software and equally important in any core Java interview, it is alway
How to implement the Command Design Pattern in Java
Publish Date:2025/03/19 Views:176 Category:ALGORITHM
-
Hello everyone, today, we will learn an important design pattern which is often overlooked by Java developers. Yes, I am talking about the Command pattern which helps us write flexible and loosely coupled code to implement actions and event
How to use the State Design Pattern in Java?
Publish Date:2025/03/19 Views:143 Category:ALGORITHM
-
The State design pattern is a behavioral pattern. The State pattern looks similar to the Strategy pattern, but it helps in managing the object states so that they behave differently in different states. In this example, we will take a famou
Observer Design Pattern in Java
Publish Date:2025/03/19 Views:70 Category:ALGORITHM
-
Observer design pattern in Java is a basic core Java pattern where the Observer monitors any changes in the state or properties of the Subject . For example, a company updates all shareholders about any decision taken by them here the compa
How to use Composite Design Pattern in Java?
Publish Date:2025/03/19 Views:179 Category:ALGORITHM
-
Hello Java programmers, if you want to learn about Composite Design Pattern in Java , such as how to implement Composite Design Pattern and when to use it, then you have come to the right place. In this article, we will discuss Composite De
Why do you need to bind event handlers in React Class Components?
Publish Date:2025/03/16 Views:58 Category:React
-
When using React, we must have come across control components and event handlers. We need to use `.bind()` in the constructor of the custom component to bind these methods to the component instance. As shown in the following code:
Do you understand JavaScript closures?
Publish Date:2025/02/21 Views:111 Category:JavaScript
-
The function of a closure can be inferred from its name, suggesting that it is related to the concept of scope. A closure itself is a core concept in JavaScript, and being a core concept, it is naturally also a difficult one.
Do you know about the hidden traps in variables in JavaScript?
Publish Date:2025/02/21 Views:183 Category:JavaScript
-
Whether you're just starting to learn JavaScript or have been using it for a long time, I believe you'll encounter some traps related to JavaScript variable scope. The goal is to identify these traps before you fall into them, in order to av