茄子在线看片免费人成视频,午夜福利精品a在线观看,国产高清自产拍在线观看,久久综合久久狠狠综合

    <s id="ddbnn"></s>
  • <sub id="ddbnn"><ol id="ddbnn"></ol></sub>

  • <legend id="ddbnn"></legend><s id="ddbnn"></s>

    JavaScript實(shí)現(xiàn)設(shè)計(jì)模式中的單例模式的一些技巧總結(jié)
    來源:易賢網(wǎng) 閱讀:1017 次 日期:2016-06-27 15:57:54
    溫馨提示:易賢網(wǎng)小編為您整理了“JavaScript實(shí)現(xiàn)設(shè)計(jì)模式中的單例模式的一些技巧總結(jié)”,方便廣大網(wǎng)友查閱!

    單例模式是JavaScript項(xiàng)目中最常用的設(shè)計(jì)模式之一,下面羅列了JavaScript實(shí)現(xiàn)設(shè)計(jì)模式中的單例模式的一些技巧總結(jié),包括惰性加載與分支技術(shù)等,需要的朋友可以參考下.

    一、使用全局變量保存單例

    這是最簡單的實(shí)現(xiàn)方法

    function Person(){ 

      this.createTime=new Date(); 

    var instance=new Person(); 

    function getInstance(){ 

      return instance; 

    加載該js時(shí)就創(chuàng)建一個(gè)Person對(duì)象,保存到instance全局變量中,每次使用都取這個(gè)對(duì)象。如果一次都沒使用,那么創(chuàng)建的這個(gè)對(duì)象則浪費(fèi)了,我們可以優(yōu)化一下,

    var instance 

    function getInstance(){ 

      if(!instance){ 

        instance=new Person(); 

      } 

      return instance; 

    這樣,第一次使用時(shí)才創(chuàng)建對(duì)象。

    這個(gè)方法的缺點(diǎn)是,instance是全局的變量,在多人合作或者開發(fā)周期比較長的情況下,很難保證instance不會(huì)被其它代碼修改或覆蓋,很可能到調(diào)用的時(shí)候,發(fā)現(xiàn)instance根本就不是Person對(duì)象。

    我們考慮下使用閉包來封裝起instance,使它不再是全局變量就可以解決這個(gè)問題了

    二、閉包創(chuàng)建對(duì)象

    var getInstance(){ 

    var instance; 

    return function(){ 

        if(!instance){ 

          instance=new Person(); 

        } 

        return instance; 

      } 

    }(); 

    這樣,instance就被封裝起來了,不用擔(dān)心被修改了。

    現(xiàn)在通過getInstance()函數(shù)可以獲得單例了。新的問題,如果我通過new Person()來創(chuàng)建對(duì)象,獲得的還是多個(gè)對(duì)象,javascript又不可以像java一樣把構(gòu)造器私有化。那怎么樣可以讓多次new出來的對(duì)象都是一個(gè)實(shí)例呢?

    三、構(gòu)造函數(shù)的靜態(tài)屬性緩存實(shí)例

    先看代碼

    function Person(){ 

      //如果已經(jīng)緩存了實(shí)例,則直接返回緩存的實(shí)例 

      if(typeof Person.instance==='object'){ 

        return Person.instance; 

      } 

      this.createTime=new Date(); 

      //緩存實(shí)例 

      Person.instance=this; 

      return this; 

    從代碼可以看到,第一次new時(shí),if的條件返回false,會(huì)往下走,初始化對(duì)象,然后保存對(duì)象到Person.instance這個(gè)靜態(tài)屬性中。

    第二次new 時(shí),if的條件返回true,直接返回Person.instance,不會(huì)再往下運(yùn)行初始化的代碼。所以不管new幾次,返回的都是第一次創(chuàng)建的對(duì)象。

    這個(gè)方法的缺點(diǎn)和方法一的缺點(diǎn)一樣,Person.instance也是公開屬性,有可能會(huì)被修改。

    我們參考方法二,使用閉包來封裝一個(gè),也許就能解決該問題了

    四、重寫構(gòu)造函數(shù)

    這個(gè)方法要使用閉包,但不能像方法二那么簡單,我們需要重寫構(gòu)造函數(shù)。

    function Person(){ 

      //緩存實(shí)例 

      var instance=this; 

      this.createTime=new Date(); 

      //重寫構(gòu)造函數(shù) 

      Person=function(){ 

        return instance; 

      } 

    第一次new 時(shí),調(diào)用原始構(gòu)造函數(shù)先緩存該實(shí)例,然后再初始化,同時(shí),重寫該構(gòu)造函數(shù)。以后再new 時(shí),永遠(yuǎn)調(diào)用不到原始的構(gòu)造函數(shù)了,只能調(diào)用到重寫后的構(gòu)造函數(shù),而這個(gè)函數(shù)總是返回緩存的instance.

    上面的方法似乎沒什么問題,但通過下面的測試,可以發(fā)現(xiàn)問題

    //向原型添加屬性 

    Person.prototype.prop1=true; 

    var p1=new Person(); 

    //在創(chuàng)建初始化對(duì)象后,再次向該原型添加屬性 

    Person.prototype.prop2=true; 

    var p2=new Person(); 

    //開始測試 

    console.log(p1.prop1);//結(jié)果為true 

    console.log(p2.prop1);//結(jié)果為true 

    console.log(p1.prop2);//結(jié)果為undefined 

    console.log(p2.prop2);//結(jié)果為undefined 

    console.log(p1.constructor===Person);//結(jié)果為false 

    console.log(p2.constructor===Person);//結(jié)果為false 

    我們預(yù)期中的結(jié)果,應(yīng)該是全都是true。

    分析一下上述測試代碼

    Person.prototype.prop1=true;是在原始構(gòu)造函數(shù)的原型下增加了prop1這個(gè)屬性,并賦值

    而在執(zhí)行 var p1=new Person();之后,Person這個(gè)構(gòu)造函數(shù)已經(jīng)被重寫了

    所以Person.prototype.prop2=true;是在新的原型下增加prop2這個(gè)屬性

    var p2=new Person(); p2和p1實(shí)際上是同一個(gè)對(duì)象,即原始構(gòu)造函數(shù)創(chuàng)建的對(duì)象

    所以p1 p2都有prop1這個(gè)屬性,而沒有prop2這個(gè)屬性

    同樣的,p1 p2的constructor指向的也是原始的構(gòu)造函數(shù),而Person此時(shí)已不是原來那個(gè)函數(shù)了

    為了能按預(yù)期的結(jié)果那樣運(yùn)行,可以通過一些修改來實(shí)現(xiàn)

    function Person(){ 

      //緩存實(shí)例 

      var instance=this; 

      //重寫構(gòu)造函數(shù) 

      Person=function(){ 

        return instance; 

      } 

      //保留原型屬性 

      Person.prototype=this; 

      //實(shí)例 

      instance=new Person(); 

      //重置構(gòu)造函數(shù)引用 

      instance.constructor=Person; 

      //其他初始化 

      instance.createTime=new Date(); 

      return instance; 

    再運(yùn)行前面的測試代碼,結(jié)果都是true了。

    五、惰性加載:

    在大型或復(fù)雜的項(xiàng)目中,起到了優(yōu)化的作用:那些開銷較大卻很少用到的組件可以被包裝到惰性加載單例中,示例程序:

    /* Singleton with Private Members, step 3. */

    MyNamespace.Singleton = (function() {

     // Private members.

     var privateAttribute1 = false;

     var privateAttribute2 = [1, 2, 3];

     function privateMethod1() {

      ...

     }

     function privateMethod2(args) {

      ...

     }

     return { // Public members.

      publicAttribute1: true,

      publicAttribute2: 10,

      publicMethod1: function() {

       ...

      },

      publicMethod2: function(args) {

       ...

      }

     };

    })();

    /* General skeleton for a lazy loading singleton, step 1. */

    MyNamespace.Singleton = (function() {

     function constructor() { // All of the normal singleton code goes here.

      // Private members.

      var privateAttribute1 = false;

      var privateAttribute2 = [1, 2, 3];

      function privateMethod1() {

       ...

      }

      function privateMethod2(args) {

       ...

      }

      return { // Public members.

       publicAttribute1: true,

       publicAttribute2: 10,

       publicMethod1: function() {

        ...

       },

       publicMethod2: function(args) {

        ...

       }

      }

     }

    })();

    /* General skeleton for a lazy loading singleton, step 2. */

    MyNamespace.Singleton = (function() {

     function constructor() { // All of the normal singleton code goes here.

      ...

     }

     return {

      getInstance: function() {

       // Control code goes here.

      }

     }

    })();

    /* General skeleton for a lazy loading singleton, step 3. */

    MyNamespace.Singleton = (function() {

     var uniqueInstance; // Private attribute that holds the single instance.

     function constructor() { // All of the normal singleton code goes here.

      ...

     }

     return {

      getInstance: function() {

       if(!uniqueInstance) { // Instantiate only if the instance doesn't exist.

        uniqueInstance = constructor();

       }

       return uniqueInstance;

      }

     }

    })();

    六、使用分支單例:

    針對(duì)特定環(huán)境的代碼可以被包裝到分支型單例中,示例程序:

    /* SimpleXhrFactory singleton, step 1. */

    var SimpleXhrFactory = (function() {

     // The three branches.

     var standard = {

      createXhrObject: function() {

       return new XMLHttpRequest();

      }

     };

     var activeXNew = {

      createXhrObject: function() {

       return new ActiveXObject('Msxml2.XMLHTTP');

      }

     };

     var activeXOld = {

      createXhrObject: function() {

       return new ActiveXObject('Microsoft.XMLHTTP');

      }

     };

    })();

    /* SimpleXhrFactory singleton, step 2. */

    var SimpleXhrFactory = (function() {

     // The three branches.

     var standard = {

      createXhrObject: function() {

       return new XMLHttpRequest();

      }

     };

     var activeXNew = {

      createXhrObject: function() {

       return new ActiveXObject('Msxml2.XMLHTTP');

      }

     };

     var activeXOld = {

      createXhrObject: function() {

       return new ActiveXObject('Microsoft.XMLHTTP');

      }

     };

     // To assign the branch, try each method; return whatever doesn't fail.

     var testObject;

     try {

      testObject = standard.createXhrObject();

      return standard; // Return this if no error was thrown.

     }

     catch(e) {

      try {

       testObject = activeXNew.createXhrObject();

       return activeXNew; // Return this if no error was thrown.

      }

      catch(e) {

       try {

        testObject = activeXOld.createXhrObject();

        return activeXOld; // Return this if no error was thrown.

       }

       catch(e) {

        throw new Error('No XHR object found in this environment.');

       }

      }

     }

    })();

    更多信息請(qǐng)查看網(wǎng)絡(luò)編程
    由于各方面情況的不斷調(diào)整與變化,易賢網(wǎng)提供的所有考試信息和咨詢回復(fù)僅供參考,敬請(qǐng)考生以權(quán)威部門公布的正式信息和咨詢?yōu)闇?zhǔn)!

    2026上岸·考公考編培訓(xùn)報(bào)班

    • 報(bào)班類型
    • 姓名
    • 手機(jī)號(hào)
    • 驗(yàn)證碼
    關(guān)于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺(tái) | 手機(jī)站點(diǎn) | 投訴建議
    工業(yè)和信息化部備案號(hào):滇ICP備2023014141號(hào)-1 云南省教育廳備案號(hào):云教ICP備0901021 滇公網(wǎng)安備53010202001879號(hào) 人力資源服務(wù)許可證:(云)人服證字(2023)第0102001523號(hào)
    云南網(wǎng)警備案專用圖標(biāo)
    聯(lián)系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關(guān)注公眾號(hào):hfpxwx
    咨詢QQ:1093837350(9:00—18:00)版權(quán)所有:易賢網(wǎng)
    云南網(wǎng)警報(bào)警專用圖標(biāo)