As a software development model, monomer mode has been widely used in many object-oriented languages, and in JavaScript, the monomer pattern is widely used, but because the JavaScript language has its unique object-oriented approach, Cause it and some traditional object-oriented language although in the monomer mode of thinking is consistent, but the implementation is still different.
First, look at the definition of the singleton schema for the traditional object-oriented language: The monomer pattern is a class that can only be instantiated once and accessed through a well-known access point. This definition has two points highlighting the traditional object-oriented language characteristics, namely, class and instantiation, so for the traditional object-oriented language, the monomer pattern is based on its class and instantiation of the natural characteristics, that is, using the keyword class to define a class, the class can be instantiated by the New keyword, However, it is necessary to ensure that each time the new instantiation is followed by the same instance, or only by using new to invoke its constructor once.
Look again at the definition of the singleton pattern in javascript: A monomer is an object that divides a namespace and organizes a number of related methods and properties together, and if it can be instantiated, it can only be instantiated once. By comparing the definitions above, you will find that the monomer definition here defines the substance as an object rather than a class in the traditional object-oriented language, which also indicates that the language of JavaScript is Object-based. At the same time, it is pointed out that if it can be instantiated, it shows that in JavaScript there should be several ways to define a monomer, there is one or several can be instantiated to use the New keyword to create a single object, but this method is not the natural characteristics of JavaScript itself, Because the object created with the New keyword is actually modeled by function to define its constructor (although ES6 begins to support the class keyword, it is not yet widely supported by the browser), So how do you use JavaScript's natural features to implement monomer mode?
1 var singleton={ 2 attribute1:true , 3 attribute2:10, 4 method1:function () { 5 6 7 method2:function 8 9 10 }
This defines an object singleton, which contains several properties and methods, which are included in the page, and the object is created when JS is loaded. Called using SINGLETON.METHOD1 to invoke, it is instantiated with the page loaded in the JS parsing execution, we did not use the New keyword to instantiate the object, which is the implementation of the monomer pattern in JavaScript and the traditional object-oriented language a very big difference. This approach is simpler and easier to understand. However, there are some shortcomings in this approach, one obvious drawback is that it does not provide a namespace, other programmers if the page also defines a singleton variable, it is easy to rewrite and confuse the monomer object, so in response to this problem, it is rewritten as follows:
1 varMyspace={};2myspace.singleton={3Attribute1:true,4Attribute2:10,5METHOD1:function(){6 7 },8METHOD2:function(ARG) {9 Ten } One}
This first defines a MySpace namespace, and then mounts the monomer object singleton underneath the object, which greatly reduces the possibility of conflicts and misoperation with other programmers, even if others define a singleton variable in the global scope. Does not contaminate this single object, it implements the function of dividing the namespace and organizing some related properties and methods as described in the previous definition.
This method still has the disadvantage that all the properties and methods of the monomer object are common, the external can be accessed and modified at any time, and the closure is used to simulate the private properties and methods as follows:
1Myspace.singleton= (function(){2 varprivateattribute1=false;3 varprivateattribute1=[1,2,3];4 functionprivateMethod1 () {5 6 }7 functionprivateMethod2 () {8 9 }Ten One return { APublicAttribute1:true, -Publicattribute2:10, -PUBLICMETHOD1:function(){ theprivateattribute1=true; - privateMethod1 (); - }, -PUBLICMETHOD2:function(ARG) { +privateattribute1=[4,5,6]; - privateMethod2 (); + } A at } - -})();
Here we directly assign to the monomer object an anonymous self-executing function, in which the Var and function keywords are used to define their private properties and methods, which are not directly accessible outside the function (the monomer object outside), because the function is executed, The space in its internal scope is recycled, which is why it is possible to use closures to emulate private properties and methods. In this function (closure), at the same time, eventually return an object, which contains some public methods and properties, can be directly called outside, while these public methods are defined within the function, so can call its private properties and methods, but the outside world only through the return of public methods and properties to complete some operations, These properties cannot be called directly singleton.privatemethod1. This allows the monomer object to isolate the outside world to directly access its private properties and methods, and provide some common properties and methods to complete some operations.
This anonymous function self-executing constructed monomer mode is widely used in many JS libraries, but there is still a problem, if we do not need to use the object when loading the page, and the creation of the object is more expensive (such as the need for a large number of calculations or the need to access the DOM tree and its properties, etc.), It is reasonable to create it when it is needed, rather than to create it directly with the parsing of JS, which is called lazy loading (lazy loading), so modify the code as follows:
1Myspace.singleton= (function(){2 varuniqueinstance;3 functionConstructor () {4 varprivateattribute1=false;5 varprivateattribute1=[1,2,3];6 functionprivateMethod1 () {7 }8 functionprivateMethod2 () {9 }Ten return { OnePublicAttribute1:true, APublicattribute2:10, -PUBLICMETHOD1:function(){ -privateattribute1=true; the privateMethod1 (); - }, -PUBLICMETHOD2:function(ARG) { -privateattribute1=[4,5,6]; + privateMethod2 (); - } + A } at } - - return { -GetInstance:function(){ - if(!uniqueinstance) { -Uniqueinstance=Constructor (); in } - returnuniqueinstance; to } + } - the})();
First, a private variable uniqueinstance is defined in the anonymous function as a handle to determine if the monomer object was created, and then all the properties and methods defined for the singleton object are placed in a function called constructor, and only that function is invoked. To create the monomer object, otherwise it will not be created directly. It then returns an object that contains an getinstance method that is called externally, which is called when the method is invoked to determine the existence of the monomer object and returns it directly if it exists, otherwise calls the constructor function to construct the monomer object and return it. Finally, if we call a method of the monomer object, we need to use MySpace.Singleton.getInstance (). PUBLICMETHOD1 (), here, this singleton object is created only when we call it this way. Otherwise, the monomer object will not be created automatically, which actually implements either on-demand loading or lazy loading.
Implementation of monolithic mode in JavaScript