Home  >  Article  >  Web Front-end  >  Learn JavaScript design patterns (single case mode)_javascript skills

Learn JavaScript design patterns (single case mode)_javascript skills

WBOY
WBOYOriginal
2016-05-16 15:29:301105browse

Definition of singleton pattern: Ensure that a class has only one instance and provide a global access point to access it.

The singleton mode is a commonly used mode. There are some objects that we often only need one, such as thread pools, global caches, and browser window objects. In js development, the singleton pattern is also very widely used. Just imagine, 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 we click the login button, this floating window will only be created once. Therefore, this login floating window is suitable for singleton mode.

1. Usage scenarios of singleton mode

Before using a mode, we’d better know the usage scenarios of this mode. I have been using the singleton pattern for so long and I don’t even know it yet! What are the specific benefits of using it?

1). You can use it to divide the namespace (this is often used)

2). Use branching technology to encapsulate the differences between browsers (I’ve never used this before, it’s quite new)

3). With the help of the singleton mode, the code can be organized more consistently, making it easier to read and maintain (this has also been used)

2. The most basic singleton pattern

The simplest singleton is actually an object literal. It organizes a group of related methods and properties together.

var Singleton = {
  attr1: true , 
  attr2: 10 ,
  method1 : function(){
    alert('我是方法1');
  },
  method2 : function(){
    alert('我是方法2');
  }
};

This object can be modified. You can add properties and methods. You can also delete existing members using the delete operator. This actually violates a principle of object-oriented design: classes can be extended, but they should not be modified. If some variables need to be protected, they can be defined in a closure.

Object literals are just one of the ways to create singletons. Not all object literals are singletons. Those that are just used to imitate associative arrays or hold data are obviously not singletons.

3. Use closures to create singletons

The main purpose of closure is to protect data

// 命名空间
var BHX = {} ;
BHX.Singleton = (function(){
  // 添加自己的私有成员
  var a1 = true ;
  var a2 = 10 ;
  var f1 = function(){
    alert('f1');
  }
  var f2 = function(){
    alert('f2');
  }        
  // 把块级作用域里的执行结果赋值给我的单例对象
  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 called the module mode, which means that it can organize a batch of related methods and attributes into modules and play the role of dividing the namespace.

4. Singleton mode is used to divide the namespace

1), prevent modification of global declarations

/*using a namespace*/

var BHX = {};
BHX.Singleton = {
  attr1: true , 
  attr2: 10 ,
  method1 : function(){
    alert('我是方法1');
  },
  method2 : function(){
    alert('我是方法2');
  }        
};
BHX.Singleton.attr1;
var attr1 = false;

In this way, even if we declare the same variable outside, we can prevent attr1 from being modified to a certain extent.

2), prevent modification of other source codes

Nowadays, JavaScript code on web pages often uses more than one source, such as library code, advertising code and badge code. To avoid conflicts with your own code, you can define an object that contains all your own 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 as special code packaging

In a website with many web pages, some codes are used by all web pages, and they are usually stored in separate files; while some codes are specific to a certain web page and will not be used elsewhere. . It's best to wrap both types of code in their own singleton objects.

We often use Javascript to add functionality to forms. For the sake of smooth degradation, it is common to first create a pure HTML page that does not rely on Javascript and uses a normal submission mechanism to complete the task.

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<len; i++){
      data[inputs[i].name] = inputs[i].value;
    }

    XGP.RegPage.sendRegistration(data);
  },
  sendRegistration: function(data){
    //make an xhr request and call displayResult() when response is recieved
    ...
  },
  displayResult: function(response){
    XGP.RegPage.outputEl.innerHTML = response;
  },
  init: function(){
    XGP.RegPage.formEl =$(XGP.RegPage.Form_ID);
    XGP.RegPage.outputEl = $(XGP.RegPage.OUTPUT_ID);
    //hijack the form submission
    addEvent(XGP.RegPage.formEl, 'submit', XGP.RegPage.handleSubmit);
  }
}
//invoke initialization method after the page load
addLoadEvent(XGP.RegPage.init);

5. Lazy singleton

The singleton pattern mentioned earlier has another thing in common: singleton objects are created when the script is loaded. For singletons that are resource-intensive or expensive to configure, it is more reasonable to defer instantiation until you need to use it.

This technique is lazy loading.

The implementation steps are as follows:

1). Move all code into the constructor method

2). Full control over the calling timing (exactly what getInstance does)

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

Branching is a technique used to encapsulate differences between browsers in dynamic methods that are set at runtime.

// 分支单例 (判断程序的分支 <浏览器差异的检测>)
var Ext = {} ;
var def = false ;
Ext.More = (function(){
  var objA = {    // 火狐浏览器 内部的一些配置
      attr1:'FF属性1'
      // 属性1 
      // 属性2 
      // 方法1 
      // 方法2
  } ;
  var objB = {    // IE浏览器 内部的一些配置
      attr1:'IE属性1'
      // 属性1 
      // 属性2 
      // 方法1 
      // 方法2             
  } ;
  return (def) &#63;objA:objB;
})();
alert(Ext.More.attr1);

For example, if xhr is used frequently in a website, the browser sniffing code must be run again every time it is called, which will be seriously inefficient. It's more efficient to identify the browser-specific code once when the script loads. This is exactly what branching technology does. Of course, branching technology is not always a more efficient choice. Only one branch among two or more branches is used, and the other branches occupy memory.

When considering whether to use branching technology, you must weigh the pros and cons of shortening time and taking up more memory.

The following uses branching 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 model

Now that we know so much about singletons, let’s take a look at its disadvantages.

Since the singleton pattern provides a single point of access, it may lead to strong coupling between modules. Therefore, it is not conducive to unit testing.

In summary, singletons are still reserved for defining namespaces and implementing branching methods.

Through the introduction of the singleton pattern from seven different aspects, have you gained a deeper understanding of the singleton pattern? I hope this article can help you.

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn