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.