久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合

站長資訊網
最全最豐富的資訊網站

JavaScript經典講解之設計模式(實例詳解)

本篇文章給大家帶來了關于JavaScript中設計模式的相關知識,其中包括單例模式、組合模式、觀察者模式等等,希望對大家有幫助。

JavaScript經典講解之設計模式(實例詳解)

1 設計模式

概念

設計模式是為了解決某種問題,而設計的一套最佳解決方案。
面向對象 – 更加注重對象 – 找一種最佳的定義對象并個對象添加屬性和方法 的 方案
找到的最佳的解決方案 – 就是一種設計模式

針對不同的問題,我們會有不同的最佳解決方案 – 設計模式

常見的設計模式:

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

1.1 單例模式

數據庫連接 – 多個功能都需要操作數據庫 – 重新連接數據庫 – 1000個功能,連接1000次數據庫

注冊功能,每次注冊都需要操作數據庫 – 同一時間有1000個人在注冊

mysql數據庫有一個連接限制:最多只能支持同時又200個連接

我們連接一次數據庫,得到一個連接,多次操作數據庫,使用這一個連接其就能操作

怎么操作,讓多次執行數據庫語句使用同一個連接 – 我們就可以設計一個設計模式

設計模式:定義一個類,這個類new以后就得到一個連接,以后每次執行數據庫語句的時候,都可以從這個類中得到一個連接
單例模式:從一個類中只能得到一個對象 – 不管操作了多少次這個類,最終得出的所有連接對象都是同一個對象

讓一個類創建出來的所有對象,里面的所有屬性和方法都一模一樣。比如封裝一個類,將一些常用的操作函數作為方法放進去,以后每次都使用同一個對象來調用這些方法

正常情況,一個類創建出來的每個對象都是不一樣的。

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

單例模式就是讓這兩個對象是一樣的,也就是說,一個類永遠只有一個實例對象

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暴露在全局的變量會造成全局的污染
利用閉包解決每次都會重新定義p的問題

單例模式的核心代碼:

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()

單例模式的應用場景在封裝工具庫。

例:封裝封裝一個工具庫
單例模式 應用 封裝工具庫

     工具庫中會有很多的方法 - 方法每次的使用 應該是同一個對象使用的,而不是應該每次都有一個新對象在使用工具
       // 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;                     }                 }                 /獲取節點屬性                getStyle(ele, attr) {                     if (this.flag) {                         return window.getComputedStyle(ele)[attr];                     } else {                         return ele.currentStyle[attr];                     }                 }                  getStyle(ele, attr) {                      嘗試一段代碼   不知道會不會報錯                      嘗試成功 后面代碼沒有什么事                     嘗試失敗 會報錯 被cathch 捕獲到  會將錯誤信息放到err參數里  catch{} 里可以處理這個錯誤 也可以不處理這個錯誤對上面的錯誤代碼進行補救  錯誤不會再瀏覽器里報錯                    try {                         return window.getComputedStyle(ele)[attr];                     } catch (err) {                         return ele.currentStyle[attr];                     }                 }                 // 設置節點css屬性                 setStyle(ele, styleObj) {                     for (let attr in styleObj) {                          ele.style[attr] = styleObj[attr];                     }                 }                 // 設置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 組合模式

組合模式就是制作啟動器。多個類在實例化以后,執行起來使用一個同名的方法來啟動,這時候可以做一個啟動器,讓多個類一起啟動。

class Carousel{     init(){         console.log("輪播圖開始運行");     }}class Tab{     init(){         console.log("選項卡開始運行");     }}class Enlarge{     init(){ 		console.log("放大鏡開始運行");     }}// 這3個類要運行起來需要各自實例化,并調用每個類中的init方法,此時就可以使用組合模式做一個啟動器

組合模式制作啟動器:

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

1.4 發布訂閱模式

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

有人訂閱 有人發布
發布訂閱模式:需要一個觀察者 需要一個被觀察者 如果觀察者發現被觀察者的狀態發生了改變,就需要執行一個任務
定義一個觀察者:

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

觀察者模式,又稱發布-訂閱模式。意思是讓一個人不停的監控某件某件東西,當這個東西要發生某種行為的時候,這個人就通知一個函數執行這個行為的操作。

例:當事件的代碼寫好以后,其實這個事件就不停的監控用戶在頁面中的行為,一旦用戶觸發這個事件的時候,就調用函數處理這個事件。

p.addEventListener("click",function(){}); // 這個事件寫好以后,就一直在頁面中監控用戶行為,用戶點擊這個元素的時候,就調用函數

觀察者模式就是類似的操作,寫觀察者模式的目的,是為了給一個非元素的數據綁定一個自定義事件。

例:給一個obj綁定一個abc的事件

分析:

給一個元素綁定事件,有綁定方法,有觸發條件,有取消綁定。

要給一個對象綁定一個自定義事件。那么這個事件如何綁定,如何觸發,如何解綁這個事件。

所以:

  • 需要一個方法處理事件的綁定。
  • 需要一個方法處理如何觸發這個事件。
  • 需要一個方法處理如何解綁這個事件。

元素的事件,一個事件類型可以綁定多個處理函數。

對象的自定義事件如何讓一個事件類型綁定多個函數。

所以:

需要一個空間,存儲事件類型對應的處理函數們。

1.4.1 雛形:

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

此時,如要給這個對象綁定事件和處理函數的話,需要事件類型和處理函數作為參數,所以調用時要傳入實參

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

1.4.2 綁定

在bind方法中接收參數,并將事件類型和處理函數對應存儲起來:

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

如果給這個事件再綁定一個函數b的話,會將原來的a覆蓋掉,所以,應該先判斷,如果對應的這個數組中沒有數據就直接放進去,如果有了就應該追加

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

打印w對象的結果:

綁定后的存儲結果
JavaScript經典講解之設計模式(實例詳解)

1.4.3 觸發

觸發這個事件需要傳入觸發哪個事件類型

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

測試:

觸發測試
JavaScript經典講解之設計模式(實例詳解)

這兩個處理函數都沒有參數,如果要傳入參數的時候該怎么處理?

觸發事件的時候就要傳入實參

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

觸發事件的方法就應該處理這些參數

touch(type,...arr){ // 因為參數不定長,所以使用合并運算符     // 首先要判斷,這個事件類型是否綁定,沒有綁定不能觸發     if(!this.obj[type]){         return false;     }else{         // 處理參數:模擬系統事件的參數事件對象,將所有參數都集中在一個對象中         var e = {             type:type,             args:arr        }         // 將這個事件的所有綁定的處理函數一起調用         for(var i=0;i<this.obj[type].length;i++){             this.obj[type][i](e);         }     }}

添加一個帶參數的處理函數,并觸發事件執行:

w.bind("cl",c); // 給w對象綁定cl事件類型,執行c函數w.touch("cl","張三",20);function c(e){     console.log("我是處理函數c,打印:姓名"+e.name+",年齡"+e.age);}

結果:

帶參數的處理函數處理結果
JavaScript經典講解之設計模式(實例詳解)

1.4.5 解綁

解綁也需要知道解綁的事件類型和處理函數

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

解綁測試:

解綁測試結果
JavaScript經典講解之設計模式(實例詳解)

如果綁定事件的時候使用的匿名函數,就無法進行解綁了,所以再添加一個解綁事件所有處理函數的方法:

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

1.5 觀察者模式

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

創建觀察者:

// 創建觀察者class Observer{     // 觀察者有姓名和技能 - 技能是一個函數     constructor(name,skill){         this.name = name;         this.skill = skill    }}// 創建觀察者var bzr = new Observer('班主任',function(state){     console.log('因為'+state+'叫家長')})var xz = new Observer('校長',function(state){     console.log('因為'+state+'叫班主任')})console.log(bzr,xz)

JavaScript經典講解之設計模式(實例詳解)

創建被觀察者:

// 創建被觀察者     class Subject{         // 被觀察者有狀態 和 觀察者列表         constructor(state){             this.state = state            this.observers = []         }         // 添加觀察者         addObserver(observer){             var index = this.observers.findIndex(v=>v === observer)             if(index<0){                 this.observers.push(observer)             }         }         // 改變狀態         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)             }         }     }     // 創建被觀察者     var xm = new Subject('學習')     // 添加觀察者     xm.addObserver(bzr)     xm.addObserver(xz)     xm.addObserver(bzr)     console.log(xm)     // 改變狀態     xm.setState('玩游戲')

JavaScript經典講解之設計模式(實例詳解)


1.6 策略模式

一個問題有多種解決方案,且隨時還可以有

贊(0)
分享到: 更多 (0)
?
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合
欧美一区自拍| 亚洲激情欧美| 国产精品xvideos88| 日韩国产91| 欧美三级第一页| 久久伊人久久| 日韩一区二区三区免费播放| 久久99影视| 国产一区二区三区四区五区传媒| 成人国产精品久久| 欧美成人基地| 亚洲一区欧美激情| 日本高清久久| 久久精品一区二区国产| 亚洲午夜天堂| 91九色精品国产一区二区| 欧美天堂亚洲电影院在线观看| 伊人久久大香伊蕉在人线观看热v| 一区二区国产在线| 国产精品传媒麻豆hd| 久久精品人人| 欧美一区三区| 蜜臀久久99精品久久久久久9| 国产主播一区| 日韩在线观看中文字幕| 欧美激情99| 99久久99久久精品国产片果冰| 亚洲深爱激情| 久久av网站| 国产高清一区| 免费看一区二区三区| 成人av二区| 国产精品99久久免费观看| 99成人超碰| 国产欧美日韩亚洲一区二区三区| 伊人久久视频| 亚洲精品九九| 亚洲天堂免费电影| 亚洲精品伊人| sm久久捆绑调教精品一区| 日韩中文字幕麻豆| 高清av一区| 亚洲精品国产日韩| 日韩电影免费在线观看| 亚洲精品麻豆| 日韩中文首页| 日韩av三区| 亚洲二区免费| 免费看久久久| 亚洲丝袜美腿一区| 97精品在线| 亚洲不卡视频| 久久一区二区中文字幕| 亚洲精品高潮| 天堂va蜜桃一区二区三区| 夜夜精品视频| 久久久久九九精品影院| 亚洲欧美在线综合| 亚洲高清成人| 精品视频亚洲| 日韩精品福利一区二区三区| 999久久久精品国产| 久久三级毛片| 欧美日韩一区二区三区不卡视频 | 国产不卡人人| 国产亚洲精品美女久久久久久久久久| 91精品观看| 正在播放日韩精品| 国产精品久久久久久妇女| 美女被久久久| 欧美~级网站不卡| 日韩综合在线| 美女久久99| 日韩不卡一区二区| 亚洲乱码久久| 丝瓜av网站精品一区二区| 久久久国产亚洲精品| 国产成人精品一区二区免费看京 | 日韩一级不卡| 久久麻豆精品| 日韩欧美午夜| 成人美女视频| 久久男人av资源站| 国产在视频一区二区三区吞精| 18国产精品| 日韩一区二区三区免费视频| 美女91精品| 久久不射中文字幕| 色吊丝一区二区| 中文在线中文资源| 97精品在线| 一区二区精品伦理...| 精品国产乱码久久久久久樱花| 麻豆精品一区二区综合av| 国产精品黄色| 麻豆免费精品视频| 精品一区二区三区中文字幕视频| 国产情侣久久| 国产精品中文字幕制服诱惑| 国产视频一区二| 国产免费av国片精品草莓男男| 久久国产乱子精品免费女| 欧美一区二区三区久久| 日韩成人一级| 欧美日一区二区三区在线观看国产免 | 欧美日韩国产欧| 夜夜嗨av一区二区三区网站四季av| 尤物精品在线| 日本亚洲三级在线| 91p九色成人| 精品国产一区二区三区性色av| 国产一区二区久久久久| 偷拍精品精品一区二区三区| 日韩中文视频| av不卡免费看| 欧美一级全黄| 久久99免费视频| 国产91在线播放精品| 久久国产毛片| 日韩中文字幕一区二区三区| 日韩va亚洲va欧美va久久| 国产福利一区二区三区在线播放| 黄色网一区二区| 午夜日韩福利| 日韩国产欧美一区二区三区| 国产精品久久久免费| 中文在线а√在线8| 99亚洲视频| 国产视频一区二区在线播放| 欧美国产小视频| 91久久亚洲| 91精品日本| 中文字幕成在线观看| 国产亚洲永久域名| 国产伦精品一区二区三区千人斩| 福利欧美精品在线| 亚洲国产一区二区三区在线播放| 亚洲免费专区| 日韩成人免费| 免费美女久久99| 久久精品二区亚洲w码| 91精品一区国产高清在线gif | 国产91久久精品一区二区| 深夜福利亚洲| 麻豆精品久久久| 日韩一区二区久久| 麻豆成人91精品二区三区| 91久久国产| 里番精品3d一二三区| 尤物在线精品| 成人免费一区| 丝袜a∨在线一区二区三区不卡| 久久的色偷偷| 国产精品三上| 国产999精品在线观看| 日韩影院精彩在线| 91日韩欧美| 最新亚洲国产| 日韩精品影视| 久久精品99国产国产精| 欧美日韩三区| 日韩在线二区| 国产精品日韩精品中文字幕| 精品1区2区3区4区| 高清一区二区| 国产欧美69| 亚洲日本国产| 中日韩男男gay无套| 天堂av在线| 国产精品xvideos88| 香蕉久久久久久| 黄色亚洲在线| 日韩中文首页| 久久影院一区二区三区| 免费不卡在线视频| 午夜日韩av| 免费污视频在线一区| 麻豆一区二区在线| 亚洲日本国产| 鲁大师成人一区二区三区 | 日韩精品一级| 欧美特黄a级高清免费大片a级| 福利视频一区| 国产激情欧美| 青青草国产精品亚洲专区无| 另类国产ts人妖高潮视频| 欧美激情另类| 国产激情综合| 欧美亚洲国产日韩| 亚洲区国产区| 日韩中文字幕91| 美女国产一区| 亚洲专区欧美专区| 影音先锋国产精品| 五月天久久网站| 亚洲国内欧美| 久久中文亚洲字幕| 欧美午夜精彩| 婷婷综合在线| 午夜影院欧美|