Ensure that a class has only one instance and provide a global access point to access it
The idea of the singleton pattern is that a class can return a reference to an object (and always be the same) and a method (a static method, usually using the getInstance name) to get that instance. So when we call this method, we return the reference that the class holds if it is not empty, otherwise we create an instance of the class, assign the instance reference to the reference that the class holds and return it. The constructor of the class is also defined as a private method, so that other functions can not use the constructor to instantiate the object, and only the static method of the class can get the unique instance of the class.
Application scenarios
In daily development, we often need to create a translucent mask layer for popovers. To reduce unnecessary DOM manipulation, the correct way to think about it is to determine whether the Model DIV has been generated before and not to generate it again.
Implementation steps
Step 1 Write a method that generates a Model div
<style>
.modal {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
opacity:.5;
background: # 000;
z-index: 99;
}
</style>
<script>
function createModal () {
const div = document.createElement('div');
div.className = 'modal';
document.body.appendChild(div);
}
createModal()
createModal() // Calling it twice produces two modal boxes
</script>
Copy the code
Calling the createModal method twice will result in appending two divs to the body, which is obviously not what we want, and we need to add a variable to determine if it has already been called
Implement according to the definition of singleton pattern
- Ensure that there is only one instance of a class
new createModal()
- And provide a global access point to access it
createModal.getInstance
Methods to access
function createModal () {
const div = document.createElement('div');
div.className = 'modal';
document.body.appendChild(div);
}
createModal.getInstance = function () {
if (this.instace) {
return this.instace;
} else {
this.instace = new createModal();
return this.instace; }};const a = createModal.getInstance()
const b = createModal.getInstance() // Call two instances once
console.log(a === b) // true
Copy the code
This section of code according to the singleton pattern definition to use JS to implement a singleton pattern, call many times will only instance a createModal, generate a modal box
Inert singleton
Due to the nature of JS, a private variable can be protected in the form of a closure that serves as a judgment value, and lazy functions represent object instances that are created when needed, not when the page loads
const createModal = (function(){
let div;
return function(){
if(! div){ div =document.createElement('div');
div.className = 'modal';
document.body.appendChild(div); }}}) (); createModal() createModal()// Call div twice to generate div once
Copy the code
With closures, div variables are protected and judged at call time
General pattern
If we need to create another div, we can only copy the code. Can we find a way to separate the div method from the return method?
- To create a
getSingle
methodsresult
Is the judgment variable - To create a
createModal
Method to execute the code and return a bool togetSingle
In theresult
judge
const getSingle = function (fn) {
let result;
return function () {
return result || (result = fn.apply(this.arguments)); }};const createModal = function () {
const div = document.createElement('div');
div.className = 'modal';
document.body.appendChild(div);
return div
}
const createSingleDiv = getSingle(createModal)
const a = createSingleDiv()
const b = createSingleDiv()
console.log(a === b) // true
Copy the code
This creates a general pattern for creating lazy singletons
conclusion
Singleton pattern is widely used in practical development, especially in framework design. Rational use can improve performance.