Original blog address, welcome to discuss, star

I came across someone implementing a pretty good singleton pattern using ES6’s class syntax, and I thought I’d combine some of the practical examples I’ve encountered and discussed online to see how singleton plays and applies in javascript.

Singleton pattern in ES3/ES5

In ES3/ES5, there is no such syntax as class. When I first encountered design patterns, most tutorials on the Web were explained in Java, because as an object-oriented language it really seemed to be intuitive to explain these design patterns. For example, the singleton pattern ensures that there is only one instance of a class. Generally, the implementation method is to check whether the instance exists or not, and return directly if there is, and create and return if there is not, which ensures that a class has only one instance object.

In javascript, there’s no such thing as a class; they’re all objects, so implementing a singleton in one typically returns an object with a child function that has a method to get an instance, and checks whether it exists when it gets it. As follows:

var Single = (function(){
  var instance;
  /* * There are also private methods that can be defined, mainly using the closure */
  function get() {
    /* * returns the last object used */
    return {
      doSomething: function () {
        console.log("AAA")}}}return {
    getInstance () {
      return instance || (instance = get()) // If the instance variable has a value, it is returned directly. If it has no value, the generated object is returned and assigned to instance}}}) ()var instance1 = Single.getInstance()
var instance2 = Single.getInstance()
console.log(instance1 === instance2) // true
Copy the code

In ES3/ES5 the singleton pattern is typically implemented using the above organization, so let’s take a look at the scenario after ES6.

ES6 later uses class syntax sugar

ES6 introduces the class keyword, a concise set of syntactic sugar used to implement js constructors. If you are not familiar with the usage of class, you can click ruan’s INTRODUCTION to ES6 to learn. First look at the code:

const single =  'single' // Use symbol instead
class A {
  static get instace () {
    if (this[single]) { // Since this is A static function, this refers to A, not the object generated by new A().
      return this.single
    }
    return this[single] = new this(a)// New constructor if there is no value
  }

  constructor() {
    const sourceClass = this.constructor // Get the constructor object
    if(! sourceClass[single]) {// Determine if the object already has a singleton
      sourceClass[single] = this // This refers to an already constructed object, which is empty, but its constructor points to A
    }
    return sourceClass[single] // Return if it already exists}}Copy the code

The above code, which requires a bit of ES6 knowledge to understand, has two methods in this “class” to generate instances.

  • The first is the constructor, which decides to return an instance
  • The second is that if there is a static property it will also return an instance by judgment. It’s used inthisTo point toAThis constructor (which is also an object) is also commented in my code. The key point is, according to the specificationkeyTo mount the instance, but with better encapsulation.

Single example implementation using NodeJS modularization

Each module in the current nodeJS and ES6 modularity is actually a singleton. Let’s take a look at the code:

class A {
  doSomething() { ... }
}
modules.export = new A() // Generate the object directly and export it
Copy the code

Because nodeJS and ES6 only load the code once for each module, the second, third, and so on, the code is checked from the cache to see if it has already been loaded and used directly.

  • So let’s first create onea.js“And just type a sentence inside.
  • Open thenode, import this file.
  • Let’s check it outmodule

    You can see that the module has been stored, and then you can go back and determine whether the module code needs to be executed based on the ID (the module path).

Some application scenarios

  • The web pageloading, the entire web page can create only one instance, according to the different parameters passed to render different styles or behaviors, global universal.
  • nodejsInside the database link instance, access to create a link is very consumption of resources, so is the global query operation is unified use of an instance.

conclusion

The singleton pattern is still very simple and very useful. It is also possible to use ES6 proxies to modify object creation to achieve singletons. These are just implementation methods, and we need to think a lot about those scenarios and design patterns to make the code scalable and reusable and so on.