What is singleton mode
Singleton Pattern ensures that a class has only one instance and provides a global access point to access it
Singleton pattern is a simple and easy to understand design pattern, but its usage scenarios are very wide, including the famous Vuex also uses singleton pattern.
This article introduces two implementation methods of singleton pattern: class and closure. It also introduces singleton pattern in Vuex.
Realization way
Class is a new syntax of ES6. Before we want to create a new object instance, it is implemented through the new constructor. Every time we call new, we will generate a new instance object. Each instance object is completely independent.
function Car (name) { this.name = name; } var car1 = new Car('benz'); var car2 = new Car('audi'); console.log(car1 === car2) // false
So let's think about how to return the same instance object every time new?
There must be a variable to save the instance object generated by new for the first time. When new is executed later, it will directly return the instance object generated for the first time, thus realizing a single instance.
Let's practice it in two ways: classes and closures.
Class implementation
class SingletonCar { constructor () { this.name = 'benz'; } static getInstance () { if (!SingletonCar.instance) { SingletonCar.instance = new SingletonCar(); } return SingletonCar.instance; } } let car1 = SingletonCar.getInstance(); let car2 = SingletonCar.getInstance(); console.log(car1 === car2) // true
Class is the prototype of an instance. All methods defined in the class will be inherited by the instance. If the static keyword is added before a method, it means that the method will not be inherited by the instance, but called directly through the class, which is called "static method".
Static methods can be called directly on the parent class SingletonCar.getInstance(), rather than on the instance object. If you call a static method on an instance, an error is thrown indicating that the method does not exist.
Class is used to implement singleton mode. Just remember the static getInstance() method.
Closure implementation
var SingletonCar = (function () { var instance; var SingletonCarTemp = function () { this.name = 'benz'; }; return function () { if (!instance) { instance = new SingletonCarTemp(); } return instance; } })(); var car1 = new SingletonCar(); var car2 = new SingletonCar(); console.log(car1 === car2) // true
With the help of closures, the instance variable is reserved in memory and will not be garbage collected. It is used to save the only instance. When new is called multiple times, only the first instance created is returned.
Singleton mode in Vuex
Vuex is the state management class library of Vue, similar to Redux to React. In fact, their ideas are all from the Flux architecture. They use a global Store to Store all the states of the application, and then provide some API s for users to read and modify. As soon as you see the globally unique Store, you can think of the singleton mode.
How to reference Vuex
import Vue from 'vue' import Vuex form 'vuex' import store from './store' Vue.use(Vuex) new Vue({ el: '#app', store })
Vuex is a plug-in. You can install the plug-in by calling the Vue.use() method. For details, please refer to Official documents
Vuex internally implements an install method, which will be called when Vue.use(), and Vue will be passed into the install method as a parameter to inject the Store into Vue. But if you have tried to call Vue.use(Vuex) multiple times in the development environment, you will know that the browser will report an error. Next, let's look at the internal implementation of vuex.
How does Vuex guarantee a unique Store
Part of the source code of upper Vuex:
let Vue ... export function install (_Vue) { // Whether Vue.use(Vuex) has been executed. If it is executed multiple times in a non production environment, an error will be prompted if (Vue && _Vue === Vue) { if (process.env.NODE_ENV !== 'production') { console.error( '[vuex] already installed. Vue.use(Vuex) should be called only once.' ) } return } // If Vue.use(Vuex) is executed for the first time, the incoming Vue is assigned to the defined variable Vue Vue = _Vue // Vuex initialization logic applyMixin(Vue) }
The full source path is in vuex/src/store.js
We can see that in Vuex, a variable Vue is defined first. Note that this is not the real Vue, but a variable, also called Vue.
When Vue.use(Vuex), the install method will be called, and the real Vue will be passed in as a parameter. If you execute Vue.use(Vuex) multiple times, it will only take effect once, that is, applyMixin(Vue) will only be executed once, so there will only be a unique Store, which is the implementation of the singleton mode in Vuex.
Practice
Implement a globally unique Loading mask.
thinking
In the process of business development, there are many requirements with Loading status. At this time, we will directly take out the single instance mode, and remember the above getInstance static method or closure instance variable, which can be implemented by dividing three times, five times and two times.
Complete code
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Single mode Global Loading</title> <style> .loading { width: 100vw; height: 100vh; line-height: 100vh; position: absolute; top: 0; left: 0; background-color: #000; opacity: .7; color: #fff; text-align: center; } </style> </head> <body> <button id="startLoading">Click load</button> <script> const Loading = (function () { let instance return function () { if (!instance) { instance = document.createElement('div') instance.innerHTML = 'Loading...' instance.id = 'loading' instance.className = 'loading' document.body.appendChild(instance) } return instance } })() document.getElementById('startLoading').addEventListener('click', () => { const loading = new Loading() }) </script> </body> </html>
summary
The singleton mode is to ensure that a class has only one instance. If it is implemented by class, remember the getInstance static method. If it is implemented by closure, remember the instance variable. When we are in business development, when we need a globally unique state like Vuex, it is when the singleton mode is launched.