After studying the factory pattern together in our last article, JavaScript Design Patterns — Factory Patterns, let’s move on to another design pattern, the singleton pattern.
define
Singleton pattern: Ensure that a class has only one instance and provide a global access point to access it. No matter how many times it is created, only the unique instance created the first time is returned.
The singleton pattern is a type of creative design pattern. For scenarios where only one object is needed globally.
Welcome to follow my wechat official account: FrontGeek
Implementation approach
In JavaScript, how can we ensure that there is only one instance of a class?
Normally, we create a class (essentially a constructor) that can be called with the new keyword to generate any number of instance objects, for example:
class SingleLoading {
show () {
console.log('This is a singleton Loading')}}let loading1 = new SingleLoading()
let loading2 = new SingleLoading()
console.log(loading1 === loading2) // false
Copy the code
In the above code, we successively new loading1 and loading2 instance objects, which are independent of each other and occupy a chunk of memory space.
And what the singleton pattern wants to do is, no matter how many times we create it, it just returns to you the only instance that was created the first time.
To do this, you need the constructor to have the ability to determine whether it has already created an instance.
Now we write the judgment logic as a static method or directly into the body of the constructor.
implementation
The singleton pattern can be implemented in two main ways: static methods and closures.
Static method implementation
Let’s statically transform the above example into a singleton pattern:
// Static method implementation
class SingleLoading {
show () {
console.log('This is a singleton Loading')}static getInstance(){
// Determine whether an instance has been created
if(! SingleLoading.instance) {// Hold the created instance object
SingleLoading.instance = new SingleLoading()
}
return SingleLoading.instance
}
}
const loading1 = SingleLoading.getInstance()
const loading2 = SingleLoading.getInstance()
console.log(loading1 === loading2) // true
Copy the code
There is a static keyword in the code above. Adding static before the getInstance method means that the method is not inherited by the instance, but is called directly from the class. This is called a “static method”.
closure
The getInstance logic can also be implemented as a closure:
/ / closures
/ / closures
class SingleLoading {
show () {
console.log('This is a singleton Loading')
}
}
SingleLoading.getInstance = (function(){
// Define a free variable instance to simulate a private variable
let instance = null
return function(){
if(! instance) {// If null, the new instance is unique
instance = new SingleLoading()
}
return instance
}
})();
const loading3 = new SingleLoading().getInstance()
const loading4 = new SingleLoading().getInstance()
console.log(loading3 === loading4)
Copy the code
With closures, instance variables are kept in memory, not garbage collected, used to hold unique instances, and only the first instance created is returned when new is called multiple times.
Bo practice
Now that we’ve learned how to implement the singleton pattern using static methods and closures, we’ll reinforce it with a classic interview question.
Implement a globally unique Modal box
The code implementation is as follows:
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<title>The singleton mode is displayed</title>
</head>
<style>
#modal {
height: 200px;
width: 200px;
line-height: 200px;
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
border: 1px solid # 999;
text-align: center;
}
</style>
<body>
<button id="open">Open the popup window</button>
<button id="close">Close Windows</button>
</body>
<script>
const Modal = (function(){
let modal = null;
return function() {
if(! modal) { modal =document.createElement('div')
modal.innerHTML = 'Globally unique Modal popover'
modal.id = 'modal'
modal.style.display = 'none'
document.body.appendChild(modal)
}
return modal
}
})()
document.getElementById('open').addEventListener('click'.function (){
const modal = new Modal()
modal.style.display = 'block'
})
document.getElementById('close').addEventListener('click'.function (){
const modal = new Modal()
modal.style.display = 'none'
})
</script>
</html>
Copy the code
The above is implemented using closures, but you can also try to implement it statically.
conclusion
The core of the singleton pattern is to ensure that there is only one instance of a class.
For singleton implementations, if class is used, remember the getInstance static method; If you implement it with a closure, remember the instance variable.
The singleton pattern can be found in many good front-end libraries. For example, Vuex and Redux, two state-management libraries, both implement a global Store for storing all application states. This Store implementation is a typical application of the singleton pattern. Interested can download the corresponding source code to study.
Finally, the advantages and disadvantages of single example mode are summarized:
- Advantages: Applicable to a single object, only one object instance is generated, avoiding frequent creation and destruction of instances, reducing memory consumption.
- Disadvantages: Not applicable to dynamically extending objects or scenarios where multiple similar objects need to be created.
See Singleton-Pattern for example code for this article
Refer to the article
- JavaScript Design Pattern 1: Singleton pattern
- Core principles and application practice of JavaScript design pattern
If you find this helpful:
1. Click “like” to support it, so that more people can see this article
2, pay attention to the public account: FrontGeek technology (FrontGeek), we learn and progress together.