久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長(zhǎng)資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      JavaScript經(jīng)典講解之設(shè)計(jì)模式(實(shí)例詳解)

      本篇文章給大家?guī)?lái)了關(guān)于JavaScript中設(shè)計(jì)模式的相關(guān)知識(shí),其中包括單例模式、組合模式、觀察者模式等等,希望對(duì)大家有幫助。

      JavaScript經(jīng)典講解之設(shè)計(jì)模式(實(shí)例詳解)

      1 設(shè)計(jì)模式

      概念

      設(shè)計(jì)模式是為了解決某種問(wèn)題,而設(shè)計(jì)的一套最佳解決方案。
      面向?qū)ο?– 更加注重對(duì)象 – 找一種最佳的定義對(duì)象并個(gè)對(duì)象添加屬性和方法 的 方案
      找到的最佳的解決方案 – 就是一種設(shè)計(jì)模式

      針對(duì)不同的問(wèn)題,我們會(huì)有不同的最佳解決方案 – 設(shè)計(jì)模式

      常見(jiàn)的設(shè)計(jì)模式:

      • 單例模式
      • 組合模式
      • 觀察者模式
      • 命令模式
      • 代理模式
      • 工廠模式
      • 策略模式
      • 適配器模式
      • 。。。

      1.1 單例模式

      數(shù)據(jù)庫(kù)連接 – 多個(gè)功能都需要操作數(shù)據(jù)庫(kù) – 重新連接數(shù)據(jù)庫(kù) – 1000個(gè)功能,連接1000次數(shù)據(jù)庫(kù)

      注冊(cè)功能,每次注冊(cè)都需要操作數(shù)據(jù)庫(kù) – 同一時(shí)間有1000個(gè)人在注冊(cè)

      mysql數(shù)據(jù)庫(kù)有一個(gè)連接限制:最多只能支持同時(shí)又200個(gè)連接

      我們連接一次數(shù)據(jù)庫(kù),得到一個(gè)連接,多次操作數(shù)據(jù)庫(kù),使用這一個(gè)連接其就能操作

      怎么操作,讓多次執(zhí)行數(shù)據(jù)庫(kù)語(yǔ)句使用同一個(gè)連接 – 我們就可以設(shè)計(jì)一個(gè)設(shè)計(jì)模式

      設(shè)計(jì)模式:定義一個(gè)類(lèi),這個(gè)類(lèi)new以后就得到一個(gè)連接,以后每次執(zhí)行數(shù)據(jù)庫(kù)語(yǔ)句的時(shí)候,都可以從這個(gè)類(lèi)中得到一個(gè)連接
      單例模式:從一個(gè)類(lèi)中只能得到一個(gè)對(duì)象 – 不管操作了多少次這個(gè)類(lèi),最終得出的所有連接對(duì)象都是同一個(gè)對(duì)象

      讓一個(gè)類(lèi)創(chuàng)建出來(lái)的所有對(duì)象,里面的所有屬性和方法都一模一樣。比如封裝一個(gè)類(lèi),將一些常用的操作函數(shù)作為方法放進(jìn)去,以后每次都使用同一個(gè)對(duì)象來(lái)調(diào)用這些方法

      正常情況,一個(gè)類(lèi)創(chuàng)建出來(lái)的每個(gè)對(duì)象都是不一樣的。

      class Carousel{     }var a = new Carousel();var b = new Carousel();console.log(a === b); // false

      單例模式就是讓這兩個(gè)對(duì)象是一樣的,也就是說(shuō),一個(gè)類(lèi)永遠(yuǎn)只有一個(gè)實(shí)例對(duì)象

      var single = (function(){     class Carousel{             }     var res = undefined;     return function(){         if(!res){            res = new Carousel();         }         return res;     }})();var s1 = single();var s2 = single();console.log(s1 === s2); // true

      變量P暴露在全局的變量會(huì)造成全局的污染
      利用閉包解決每次都會(huì)重新定義p的問(wèn)題

      單例模式的核心代碼:

      function Person(){}function fn(Person){     var p;     return function(){         if(!p){             p = new Person;         }         return p;     }}var f = fn(Person)var p1 = f()var p2 = f()

      單例模式的應(yīng)用場(chǎng)景在封裝工具庫(kù)。

      例:封裝封裝一個(gè)工具庫(kù)
      單例模式 應(yīng)用 封裝工具庫(kù)

           工具庫(kù)中會(huì)有很多的方法 - 方法每次的使用 應(yīng)該是同一個(gè)對(duì)象使用的,而不是應(yīng)該每次都有一個(gè)新對(duì)象在使用工具
             // var t = new Tool;         // t.setCookie('username', 'zs', 20);         const Tool = (function () {             class Tool {                 constructor() {                     if (window.getComputedStyle) {                         this.flag = true;                     } else {                         this.flag = false;                     }                 }                 /獲取節(jié)點(diǎn)屬性                getStyle(ele, attr) {                     if (this.flag) {                         return window.getComputedStyle(ele)[attr];                     } else {                         return ele.currentStyle[attr];                     }                 }                  getStyle(ele, attr) {                      嘗試一段代碼   不知道會(huì)不會(huì)報(bào)錯(cuò)                      嘗試成功 后面代碼沒(méi)有什么事                     嘗試失敗 會(huì)報(bào)錯(cuò) 被cathch 捕獲到  會(huì)將錯(cuò)誤信息放到err參數(shù)里  catch{} 里可以處理這個(gè)錯(cuò)誤 也可以不處理這個(gè)錯(cuò)誤對(duì)上面的錯(cuò)誤代碼進(jìn)行補(bǔ)救  錯(cuò)誤不會(huì)再瀏覽器里報(bào)錯(cuò)                    try {                         return window.getComputedStyle(ele)[attr];                     } catch (err) {                         return ele.currentStyle[attr];                     }                 }                 // 設(shè)置節(jié)點(diǎn)css屬性                 setStyle(ele, styleObj) {                     for (let attr in styleObj) {                          ele.style[attr] = styleObj[attr];                     }                 }                 // 設(shè)置cookie                 setCookie(key, value, second, path = '/') {                     let data = new Date();                     date.setTime(date.getTime() - 8 * 3600 * 1000 + second * 1000);                     document.cookie = `${key}=${value};expires=${date};path=${path}`;                 }             }             var tool;             return (function () {                 if (!tool) {                     tool = new Tool();                 }                 return tool;             })();         })();

      1.3 組合模式

      組合模式就是制作啟動(dòng)器。多個(gè)類(lèi)在實(shí)例化以后,執(zhí)行起來(lái)使用一個(gè)同名的方法來(lái)啟動(dòng),這時(shí)候可以做一個(gè)啟動(dòng)器,讓多個(gè)類(lèi)一起啟動(dòng)。

      class Carousel{     init(){         console.log("輪播圖開(kāi)始運(yùn)行");     }}class Tab{     init(){         console.log("選項(xiàng)卡開(kāi)始運(yùn)行");     }}class Enlarge{     init(){ 		console.log("放大鏡開(kāi)始運(yùn)行");     }}// 這3個(gè)類(lèi)要運(yùn)行起來(lái)需要各自實(shí)例化,并調(diào)用每個(gè)類(lèi)中的init方法,此時(shí)就可以使用組合模式做一個(gè)啟動(dòng)器

      組合模式制作啟動(dòng)器:

      class Starter{     constructor(){ 		this.arr = []; // 定義一個(gè)數(shù)組     }     add(className){         this.arr.push(className); // 將這個(gè)多個(gè)類(lèi)放進(jìn)數(shù)組     }     run(){         for(var i=0;i<this.arr.length;i++){             arr[i].init(); // 讓數(shù)組中的每個(gè)類(lèi)都調(diào)用init方法         }     }}var starts = new Starter();starts.add(new Carousel);starts.add(new Tab);starts.add(new Enlarge);starts.run();

      1.4 發(fā)布訂閱模式

      https://blog.csdn.net/weixin_44070254/article/details/117574565?spm=1001.2014.3001.5501

      有人訂閱 有人發(fā)布
      發(fā)布訂閱模式:需要一個(gè)觀察者 需要一個(gè)被觀察者 如果觀察者發(fā)現(xiàn)被觀察者的狀態(tài)發(fā)生了改變,就需要執(zhí)行一個(gè)任務(wù)
      定義一個(gè)觀察者:

      class Observer{     // 觀察者有名字和任務(wù)     constructor(name,task){         this.name = name        this.task = task    }}// 定義班主任var bzr = new Observer('班主任',function(state){     console.log("因?yàn)?quot;+state+",所以"+this.name+"罰站");})// 定義了一個(gè)年級(jí)主任var zr = new Observer('年級(jí)主任',function(state){     console.log("因?yàn)?quot;+state+",所以"+this.name+"要找班主任");})// 被觀察者class Subject{     // 有自己的狀態(tài)     constructor(state){         this.state = state        // 觀察者們         this.observer = [];     }     // 添加被觀察者     add(...arr){         this.observer = this.observer.concat(arr)     }     // 改變狀態(tài)     changeSate(state){         this.state = state        // 觸發(fā)觀察者的任務(wù)         for(let i=0;i<this.observer.length;i++){             this.observer[i].task(state)         }     }}var xm = new Subject('學(xué)習(xí)')xm.add(bzr,zr)// xm.changeSate('摸了一下小紅的手')xm.changeSate('玩游戲')

      觀察者模式,又稱發(fā)布-訂閱模式。意思是讓一個(gè)人不停的監(jiān)控某件某件東西,當(dāng)這個(gè)東西要發(fā)生某種行為的時(shí)候,這個(gè)人就通知一個(gè)函數(shù)執(zhí)行這個(gè)行為的操作。

      例:當(dāng)事件的代碼寫(xiě)好以后,其實(shí)這個(gè)事件就不停的監(jiān)控用戶在頁(yè)面中的行為,一旦用戶觸發(fā)這個(gè)事件的時(shí)候,就調(diào)用函數(shù)處理這個(gè)事件。

      p.addEventListener("click",function(){}); // 這個(gè)事件寫(xiě)好以后,就一直在頁(yè)面中監(jiān)控用戶行為,用戶點(diǎn)擊這個(gè)元素的時(shí)候,就調(diào)用函數(shù)

      觀察者模式就是類(lèi)似的操作,寫(xiě)觀察者模式的目的,是為了給一個(gè)非元素的數(shù)據(jù)綁定一個(gè)自定義事件。

      例:給一個(gè)obj綁定一個(gè)abc的事件

      分析:

      給一個(gè)元素綁定事件,有綁定方法,有觸發(fā)條件,有取消綁定。

      要給一個(gè)對(duì)象綁定一個(gè)自定義事件。那么這個(gè)事件如何綁定,如何觸發(fā),如何解綁這個(gè)事件。

      所以:

      • 需要一個(gè)方法處理事件的綁定。
      • 需要一個(gè)方法處理如何觸發(fā)這個(gè)事件。
      • 需要一個(gè)方法處理如何解綁這個(gè)事件。

      元素的事件,一個(gè)事件類(lèi)型可以綁定多個(gè)處理函數(shù)。

      對(duì)象的自定義事件如何讓一個(gè)事件類(lèi)型綁定多個(gè)函數(shù)。

      所以:

      需要一個(gè)空間,存儲(chǔ)事件類(lèi)型對(duì)應(yīng)的處理函數(shù)們。

      1.4.1 雛形:

      class watch{     bind(){              }     touch(){              }     unbind(){              }}var w = new watch();

      此時(shí),如要給這個(gè)對(duì)象綁定事件和處理函數(shù)的話,需要事件類(lèi)型和處理函數(shù)作為參數(shù),所以調(diào)用時(shí)要傳入實(shí)參

      var w = new watch();w.bind("cl",a); // 給w對(duì)象綁定cl事件類(lèi)型,執(zhí)行a函數(shù)w.bind("cl",b); // 給w對(duì)象綁定cl事件類(lèi)型,執(zhí)行b函數(shù)function a(){     console.log("事件處理函數(shù)a");}function b(){     console.log("事件處理函數(shù)b");}

      1.4.2 綁定

      在bind方法中接收參數(shù),并將事件類(lèi)型和處理函數(shù)對(duì)應(yīng)存儲(chǔ)起來(lái):

      constructor(){     this.obj = {} // 存儲(chǔ)格式:{事件類(lèi)型:[函數(shù)1,函數(shù)2]}}bind(type,handle){     this.obj[type] = [handle]; // 對(duì)象存儲(chǔ)方式{"cl":[a]}}

      如果給這個(gè)事件再綁定一個(gè)函數(shù)b的話,會(huì)將原來(lái)的a覆蓋掉,所以,應(yīng)該先判斷,如果對(duì)應(yīng)的這個(gè)數(shù)組中沒(méi)有數(shù)據(jù)就直接放進(jìn)去,如果有了就應(yīng)該追加

      bind(type,handle){     if(!this.obj[type]){         this.obj[type] = [handle]; // 對(duì)象存儲(chǔ)方式{"cl":[a]}     }else{         this.obj[type].push(handle);     }  }

      打印w對(duì)象的結(jié)果:

      綁定后的存儲(chǔ)結(jié)果
      JavaScript經(jīng)典講解之設(shè)計(jì)模式(實(shí)例詳解)

      1.4.3 觸發(fā)

      觸發(fā)這個(gè)事件需要傳入觸發(fā)哪個(gè)事件類(lèi)型

      touch(type){     // 首先要判斷,這個(gè)事件類(lèi)型是否綁定,沒(méi)有綁定不能觸發(fā)     if(!this.obj[type]){         return false;     }else{         // 將這個(gè)事件的所有綁定的處理函數(shù)一起調(diào)用         for(var i=0;i<this.obj[type].length;i++){             this.obj[type][i]();         }     }}

      測(cè)試:

      觸發(fā)測(cè)試
      JavaScript經(jīng)典講解之設(shè)計(jì)模式(實(shí)例詳解)

      這兩個(gè)處理函數(shù)都沒(méi)有參數(shù),如果要傳入?yún)?shù)的時(shí)候該怎么處理?

      觸發(fā)事件的時(shí)候就要傳入實(shí)參

      w.touch("cl","張三",20);

      觸發(fā)事件的方法就應(yīng)該處理這些參數(shù)

      touch(type,...arr){ // 因?yàn)閰?shù)不定長(zhǎng),所以使用合并運(yùn)算符     // 首先要判斷,這個(gè)事件類(lèi)型是否綁定,沒(méi)有綁定不能觸發(fā)     if(!this.obj[type]){         return false;     }else{         // 處理參數(shù):模擬系統(tǒng)事件的參數(shù)事件對(duì)象,將所有參數(shù)都集中在一個(gè)對(duì)象中         var e = {             type:type,             args:arr        }         // 將這個(gè)事件的所有綁定的處理函數(shù)一起調(diào)用         for(var i=0;i<this.obj[type].length;i++){             this.obj[type][i](e);         }     }}

      添加一個(gè)帶參數(shù)的處理函數(shù),并觸發(fā)事件執(zhí)行:

      w.bind("cl",c); // 給w對(duì)象綁定cl事件類(lèi)型,執(zhí)行c函數(shù)w.touch("cl","張三",20);function c(e){     console.log("我是處理函數(shù)c,打?。盒彰?quot;+e.name+",年齡"+e.age);}

      結(jié)果:

      帶參數(shù)的處理函數(shù)處理結(jié)果
      JavaScript經(jīng)典講解之設(shè)計(jì)模式(實(shí)例詳解)

      1.4.5 解綁

      解綁也需要知道解綁的事件類(lèi)型和處理函數(shù)

      unbind(type,handle){     // 先判斷是否綁定了這個(gè)事件     if(!this.obj[type]){         return false;     }else{         // 從數(shù)組中將這個(gè)處理函數(shù)刪除         for(var i=0;i<this.obj[type].length;i++){             if(this.obj[type][i] === type){                 this.obj[type].splice(i,1);                 i--; // 放置數(shù)組塌陷             }         }     }}

      解綁測(cè)試:

      解綁測(cè)試結(jié)果
      JavaScript經(jīng)典講解之設(shè)計(jì)模式(實(shí)例詳解)

      如果綁定事件的時(shí)候使用的匿名函數(shù),就無(wú)法進(jìn)行解綁了,所以再添加一個(gè)解綁事件所有處理函數(shù)的方法:

      clear(type){     if(!this.obj[type]){         return false;     }else{         // 直接從對(duì)象中將這個(gè)屬性刪除         delete this.obj[type];     } }

      1.5 觀察者模式

      觀察者模式跟發(fā)布訂閱模式不一樣的地方在于,要有觀察者和被觀察者。

      創(chuàng)建觀察者:

      // 創(chuàng)建觀察者class Observer{     // 觀察者有姓名和技能 - 技能是一個(gè)函數(shù)     constructor(name,skill){         this.name = name;         this.skill = skill    }}// 創(chuàng)建觀察者var bzr = new Observer('班主任',function(state){     console.log('因?yàn)?#39;+state+'叫家長(zhǎng)')})var xz = new Observer('校長(zhǎng)',function(state){     console.log('因?yàn)?#39;+state+'叫班主任')})console.log(bzr,xz)

      JavaScript經(jīng)典講解之設(shè)計(jì)模式(實(shí)例詳解)

      創(chuàng)建被觀察者:

      // 創(chuàng)建被觀察者     class Subject{         // 被觀察者有狀態(tài) 和 觀察者列表         constructor(state){             this.state = state            this.observers = []         }         // 添加觀察者         addObserver(observer){             var index = this.observers.findIndex(v=>v === observer)             if(index<0){                 this.observers.push(observer)             }         }         // 改變狀態(tài)         setState(val){             if(val!==this.state){                 this.state = val;                 this.observers.forEach(v=>{                     v.skill(this.state)                 })             }         }         // 刪除觀察者         delObserver(observer){             var index = this.observers.findIndex(v=>v === observer)             if(index>=0){                 this.observers.splice(index,1)             }         }     }     // 創(chuàng)建被觀察者     var xm = new Subject('學(xué)習(xí)')     // 添加觀察者     xm.addObserver(bzr)     xm.addObserver(xz)     xm.addObserver(bzr)     console.log(xm)     // 改變狀態(tài)     xm.setState('玩游戲')

      JavaScript經(jīng)典講解之設(shè)計(jì)模式(實(shí)例詳解)


      1.6 策略模式

      一個(gè)問(wèn)題有多種解決方案,且隨時(shí)還可以有

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)