JavaScript Design Pattern Item 6 -- Singleton
Singleton mode definition:Ensure that a class has only one instance and provides a global access point to it.
The Singleton mode is a common mode. We usually only need one of some objects, such as the thread pool, global cache, and window objects in the browser. In js development, the singleton mode is also widely used. Imagine that when we click the login button, a login box will appear on the page, and this floating window is unique, no matter how many times you click the login button, this floating window will only be created once. Therefore, this login floating window is suitable for the singleton mode.
1. Use Cases of Singleton Mode
Before using a mode, we 'd better know the application scenarios of this mode. I don't know how to use the singleton mode for so long! What are the specific advantages of using it?
1. You can use itDivide namespaces(This is often used)
2. Use the Branch TechnologyDifferences between encapsulated browsers(This is really useless, it's fresh)
3. Use the singleton mode to make the code more consistent,Easy reading and Maintenance(This is also used)
2. Basic Singleton Mode
The simplest Singleton is actually an object literal. It organizes a group of associated methods and attributes.
Var Singleton = {attr1: true, attr2: 10, method1: function () {alert ('I am method 1');}, method2: function () {alert ('I am method 2 ');}};
This object can be modified. You can add attributes and methods. You can also use the delete operator to delete an existing member. This actually violates an object-oriented design principle:Class can be extended, but should not be modified.If some variables need to be protected, they can be defined in the closure.
The object literal is only one of the methods for creating a singleton. Not all object literal volumes are singleton. The literal volume of objects that are used to mimic the associated array or to hold data is obviously not Singleton.
3. Create a singleton using a closure
Closure mainly protects data
// Namespace var BHX = {}; BHX. singleton = (function () {// Add your own private member var a1 = true; var a2 = 10; var f1 = function () {alert ('f1 ');} var f2 = function () {alert ('F2');} // assign the execution result in the block-level scope to my singleton object return {attr1: a1, attr2: a2, method1: function () {return f1 () ;}, method2: function () {return f2 () ;}}) (); alert (BHX. singleton. attr1); BHX. singleton. method1 ();
This Singleton mode is also calledModule ModeIt can organize a batch of related methods and attributes into modules and divide namespaces.
4. The Singleton mode is used to divide namespaces.
1. Prevent modifications to global declarations
/* Using a namespace */var BHX = {}; BHX. singleton = {attr1: true, attr2: 10, method1: function () {alert ('I am method 1');}, method2: function () {alert ('I am method 2') ;}}; BHX. singleton. attr1; var attr1 = false;
In this way, even if we declare the same variables outside, we can prevent the attr1 from being modified to a certain extent.
2. prevent other source code modifications
Currently, JavaScript code on Web pages often uses more than one source, library code, advertisement code, and badge code. To avoid conflicts with your own code, you can define an object that contains all your code.
var XGP = {};XGP.Common = { //A singleton with common methods used by all objects and modules}XGP.ErrorCodes = { //An object literal used to store data}XGP.PageHandler = { //A singleton with page specific methods and attributes.}
3. Used for specialized code Encapsulation
In websites with many webpages, some code is used by all webpages, which are usually stored in independent files, while some code is dedicated to a webpage, it will not be used elsewhere. We recommend that you package these two types of code in your singleton object.
We often use Javascript to add functions for forms. For the sake of stability and degradation, we usually first create a pure HTML webpage that does not rely on Javascript and uses the common commit mechanism to complete tasks.
XGP.RegPage = { FORM_ID: 'reg-form', OUTPUT_ID: 'reg-result', handleSubmit: function(e){ e.preventDefault(); //stop the normal form submission var data = {}; var inputs = XGP.RegPage.formEl.getElementByTagName('input'); for(var i=0, len=inputs.length; i
5. inert Singleton
The Singleton mode mentioned above has another thing in common: the singleton object is created when the script is loaded. For resource-intensive or configuration-intensive Singleton instances, it is more reasonable to postpone their instantiation until they need to be used.
This technology is lazy loading ).
The implementation steps are as follows:
1. Move all the code to the constructor method.
2. full control over the call time (exactly what getInstance needs to do)
XGP.lazyLoading = (function(){ var uniqInstance; function constructor(){ var attr = false; function method(){ } return { attrp: true, methodp: function(){ } } } return { getInstance: function(){ if(!uniqInstance){ uniqInstance = constructor(); } return uniqInstance; } }})();
6. Branch Technology
A branch is a technique used to encapsulate the differences between browsers in dynamic methods set during runtime.
// Branch Singleton (judge the branch of the Program <browser Difference Detection>) var Ext ={}; var def = false; Ext. more = (function () {var objA = {// some configurations in Firefox: 'ff attribute 1' // attribute 1 // attribute 2 // method 1 // method 2}; var objB = {// some internal configurations of IE browser attr1: 'ie attribute 1' // attribute 1 // attribute 2 // method 1 // method 2}; return (def )? ObjA: objB;}) (); alert (Ext. More. attr1 );
For example, if xhr is frequently used on a website, you must run the browser sniffing code again for each call, which seriously results in a lack of efficiency. It is more effective to determine the browser-specific code at one time during Script Loading. This is exactly what branch technologies do. Of course, the branch technology is not always more efficient. Only one branch is used in two or more branches, and other branches occupy the memory.
When considering whether to use the branch technology, you must weigh the advantages and disadvantages of shortening the time and occupying more memory.
The following uses the branch technology to implement XHR:
var XHR = (function(){ var standard = { createXhrObj: function(){ return new XMLHttpRequest(); } }; var activeXNew = { createXhrObj: function(){ return new ActiveXObject('Msxml2.XMLHTTP'); } }; var activeXOld = { createXhrObj: function(){ return new ActiveXObject('Microsoft.XMLHTTP'); } }; var testObj; try{ testObj = standard.createXhrObj(); return testObj; }catch(e){ try{ testObj = activeXNew.createXhrObj(); return testObj; }catch(e){ try{ testObj = activeXOld.createXhrObj(); return testObj; }catch(e){ throw new Error('No XHR object found in this environment.'); } } }})();
7. disadvantages of Singleton Mode
After learning so much about Singleton, let's take a look at its drawbacks.
Because the singleton mode provides a single point of access, it may lead to strong coupling between modules. Therefore, unit testing is not conducive.
To sum up, the singleton still leaves the namespace to define and implement the functions of the branching method.