好程式設計師web前端培訓分享JavaScript學習筆記之設計模式
好程式設計師web 前端培訓分享 JavaScript 學習筆記之設計模式, 設計模式是我們在 解決問題的時候針對特定問題給出的簡潔而最佳化的處理方案
我們有很多的設計模式
單例模式
組合模式
觀察者模式
...
今天我們就聊一下這三個設計模式
單例模式 / 組合模式 / 觀察者模式
單例模式
· 什麼是單例模式呢?
· 我們都知道,建構函式可以創造一個物件
· 我們 new 很多次建構函式就能得到很多的物件
· 單例模式: 就是使用建構函式例項化的時候,不管例項化多少回,都是同一個物件
· 也就是一個建構函式一生只能 new 出一個物件
· 也就是說,當我們使用建構函式,每一次 new 出來的物件 屬性/功能/方法 完全一樣 的時候,我們把他設計成單例模式
核心程式碼
· 單例模式的核心程式碼很簡單
· 其實就是判斷一下,他曾經有沒有 new 出來過物件
· 如果有,就還繼續使用之前的那個物件,如果沒有,那麼就給你 new 一個
// 準備一個建構函式 // 將來要 new 的 function Person() {} // 準備一個單例模式函式// 這個單例模式函式要把 Person 做成一個單例模式// 將來再想要 new Person 的時候只要執行這個 singleton 函式就可以了 function singleton () {
let instance;
if ( ! instance) { // 如果 instance 沒有內容 // 來到這裡,證明 instance 沒有內容 // 給他賦值為 new Person instance = new Person()
}
// 返回的永遠都是第一次 new Person 的例項 // 也就是永遠都是一個例項 return instance} const p1 = singleton() const p2 = singleton()console.log(p1 === p2) // true
應用
· 我們就用這個核心程式碼簡單書寫一個 demo
// 這個建構函式的功能就是建立一個 div,新增到頁面中 function CreateDiv() {
this .div = document .createElement( 'div' )
document .body.appendChild( this .div)} CreateDiv.prototype.init = function (text) {
this .div.innerHTML = text} // 準備把這個 CreateDiv 做成單例模式// 讓 singleton 成為一個閉包函式 const singleton = ( function () {
let instance
return function (text) {
if ( ! instance) {
instance = new CreateDiv()
}
instance.init(text)
return instance
}})() singleton( 'hello' ) // 第一次的時候,頁面中會出現一個新的 div ,內容是 hello singleton( 'world' ) // 第二次的時候,不會出現新的 div,而是原先的 div 內容變成了 world
組合模式
· 組合模式,就是把幾個建構函式的啟動方式組合再一起
· 然後用一個 ”遙控器“ 進行統一呼叫
class GetHome {
init () {
console.log( '到家了' )
}} class OpenComputer {
init () {
console.log( '開啟電腦' )
}} class PlayGame {
init () {
console.log( '玩遊戲' )
}}
· 上面幾個建構函式的創造的例項化物件的 啟動方式 都一致
· 那麼我們就可以把這幾個函式以組合模式的情況書寫
· 然後統一啟動
· 準備一個 組合模式 的建構函式
class Compose {
constructor () {
this .compose = []
}
// 新增任務的方法 add (task) {
this .compose.push(task)
}
// 一個執行任務的方法 execute () {
this .compose.forEach(item => {
item.init()
})
}}
· 我們就用我們的組合模式建構函式來吧前面的幾個功能組合起來
const c = new Compose() // 把所有要完成的任務都放在佇列裡面 c.add( new GetHome())c.add( new OpenComputer)c.add( new PlayGame) // 直接器動任務佇列 c.execute() // 就會按照順序執行三個物件中的 init 函式
觀察者模式
· 觀察者模式,通常也被叫做 釋出-訂閱模式 或者 訊息模式
· 英文名稱叫做 Observer
· 官方解釋: 當一個物件的狀態發生改變時,所有依賴於它的物件都得到通知並被自動更新,解決了主體物件與觀察者之間功能的耦合,即一個物件狀態改變給其他物件通知的問題
· 聽起來很迷糊,但是其實沒有很難
一個例子
· 當你想去書店買書,但是恰巧今天你要買的書沒有了
· 我們又不能總在書店等著,就把我們的手機留給店員
· 當你需要的書到了的時候,他會打電話通知你,你去買了就好了
· 你買到數了以後,就告訴他,我買到了,那麼以後再來了書就不會通知你了
addEventListener
· 上面的例子可能還不是很明確
· 但是 addEventListener 是一個我們都用過的東西
· 這個東西其實就是一個標準的 觀察者模式
btn.addEventListener( 'click' , function () {
console.log( 'btn 被點選了' )})
· 上面這個就是有一個 無形的觀察者 再觀察著 btn 的一舉一動
· 當這個 btn 被點選的時候,就會執行 對應的函式
· 我們也可以多繫結幾個函式
· 說白了: 觀察者模式就是我們自己實現一個 addEventListener 的功能
· 只不過 addEventListaner 只有固定的一些事件,而且只能給 dom 元素繫結
· 而我們自己寫的可以隨便繫結一個事件名稱,自己選擇觸發時機而已
書寫程式碼
· 首先我們分析功能
· 我們要有一個觀察者(這裡抽象為一個物件 {} )
· 需要有一個屬性,存放訊息的盒子(把你繫結的所有事件放在裡面)
· 需要一個 on 方法,用於新增事件
· 需要一個 emit 方法,用於釋出事件(觸發)
· 需要一個 off 方法,把已經新增的方法取消
const observer = {
message : {},
on : function () {},
emit : function () {},
off : function () {}}
· 我們把它寫成一個建構函式的形式
class Observer {
constructor () {
this .message = {}
}
on () {}
emit () {}
off () {}}
· 現在,一個觀察者的雛形就出來了
· 接下來完善方法就可以了
ON
· 先來寫 ON 方法
· 新增一個事件
· 我們的 on 方法需要接受 兩個引數
· 事件型別
· 事件處理函式
class Observer {
constructor () {
this .message = {}
}
on(type, fn) {
// 判斷訊息盒子裡面有沒有設定事件型別 if ( !this .message[type]) {
// 證明訊息盒子裡面沒有這個事件型別 // 那麼我們直接新增進去 // 並且讓他的值是一個陣列,再陣列裡面放上事件處理函式 this .message[type] = [fn]
} else {
// 證明訊息盒子裡面有這個事件型別 // 那麼我們直接向陣列裡面追加事件處理函式就行了 this .message[type].push(fn)
}
}
emit () {}
off () {}}
EMIT
· 接下來就是釋出事件
· 也就是讓我們已經訂閱好的事件執行一下
· 同樣需要接受兩個引數
· 要觸發的事件型別
· 給事件處理函式傳遞的引數
class Observer {
constructor () {
this .message = {}
}
on(type, fn) {
// 判斷訊息盒子裡面有沒有設定事件型別 if ( !this .message[type]) {
// 證明訊息盒子裡面沒有這個事件型別 // 那麼我們直接新增進去 // 並且讓他的值是一個陣列,再陣列裡面放上事件處理函式 this .message[type] = [fn]
} else {
// 證明訊息盒子裡面有這個事件型別 // 那麼我們直接向陣列裡面追加事件處理函式就行了 this .message[type].push(fn)
}
}
emit(type, ...arg) {
// 判斷你之前有沒有訂閱過這個事件 if ( !this .message[type]) return
// 如果有,那麼我們就處理一下引數 const event = {
type : type,
arg : arg || {}
}
// 迴圈執行為當前事件型別訂閱的所有事件處理函式 this .message[type].forEach(item => {
item.call( this , event)
})
}
off() {}}
OFF
· 最後就是移除事件
· 就是把已經訂閱的事件處理函式移除掉
· 同樣需要接受兩個引數
· 要移除的事件型別
· 要移除的事件處理函式
class Observer {
constructor () {
this .message = {}
}
on(type, fn) {
// 判斷訊息盒子裡面有沒有設定事件型別 if ( !this .message[type]) {
// 證明訊息盒子裡面沒有這個事件型別 // 那麼我們直接新增進去 // 並且讓他的值是一個陣列,再陣列裡面放上事件處理函式 this .message[type] = [fn]
} else {
// 證明訊息盒子裡面有這個事件型別 // 那麼我們直接向陣列裡面追加事件處理函式就行了 this .message[type].push(fn)
}
}
emit(type, ...arg) {
// 判斷你之前有沒有訂閱過這個事件 if ( !this .message[type]) return
// 如果有,那麼我們就處理一下引數 const event = {
type : type,
arg : arg || {}
}
// 迴圈執行為當前事件型別訂閱的所有事件處理函式 this .message[type].forEach(item => {
item.call( this , event)
})
}
off (type, fn) {
// 判斷你之前有沒有訂閱過這個事件 if ( !this .message[type]) return
// 如果有我們再進行移除 for ( let i = 0 ; i < this .message[type].length; i ++ ) {
const item = this .message[type][i]
if (item === fn) {
this .message[type].splice(i, 1 )
i --
}
}
}}
· 以上就是最基本的 觀察者模式
· 接下來我們就使用一下試試看
使用一下
const o = new Observer() // 準備兩個事件處理函式 function a(e) {
console.log( 'hello' )} function b(e) {
console.log( 'world' )} // 訂閱事件 o.on( 'abc' , a)o.on( 'abc' , b) // 釋出事件(觸發) o.emit( 'abc' , '100' , '200' , '300' ) // 兩個函式都回執行 // 移除事件 o.off( 'abc' , 'b' ) // 再次釋出事件(觸發) o.emit( 'abc' , '100' , '200' , '300' ) // 只執行一個 a 函式了
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69913864/viewspace-2701905/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 好程式設計師web前端培訓分享JavaScript學習筆記Promise程式設計師Web前端JavaScript筆記Promise
- 好程式設計師web前端培訓分享JavaScript學習筆記SASS程式設計師Web前端JavaScript筆記
- 好程式設計師web前端培訓分享JavaScript學習筆記cookie程式設計師Web前端JavaScript筆記Cookie
- 好程式設計師web前端培訓分享JavaScript學習筆記之陣列程式設計師Web前端JavaScript筆記陣列
- 好程式設計師web前端培訓分享JavaScript學習筆記之正則程式設計師Web前端JavaScript筆記
- 好程式設計師web前端培訓分享學習JavaScript程式設計師Web前端JavaScript
- 好程式設計師web前端培訓分享JavaScript學習筆記之ES5程式設計師Web前端JavaScript筆記
- 好程式設計師web前端培訓分享node學習筆記程式設計師Web前端筆記
- 好程式設計師web前端培訓JavaScript學習筆記DOM程式設計師Web前端JavaScript筆記
- 好程式設計師web前端培訓JavaScript學習筆記--jQuery程式設計師Web前端JavaScript筆記jQuery
- 好程式設計師web前端培訓分享JavaScript學習筆記分支結構程式設計師Web前端JavaScript筆記
- 好程式設計師web前端培訓分享JavaScript學習指南程式設計師Web前端JavaScript
- 好程式設計師web前端培訓分享JavaScript學習筆記之迴圈結構程式設計師Web前端JavaScript筆記
- 好程式設計師web前端培訓分享HTMLCSS學習筆記BFC程式設計師Web前端HTMLCSS筆記
- 好程式設計師web前端培訓分享React學習筆記(一)程式設計師Web前端React筆記
- 好程式設計師web前端培訓分享React學習筆記(二)程式設計師Web前端React筆記
- 好程式設計師web前端培訓分享React學習筆記(三)程式設計師Web前端React筆記
- 好程式設計師web前端培訓分享JavaScript學習筆記函式進階程式設計師Web前端JavaScript筆記函式
- 好程式設計師web前端培訓分享JavaScript學習筆陣列的排序程式設計師Web前端JavaScript陣列排序
- 好程式設計師web前端培訓分享JavaScript學習筆記閉包與繼承程式設計師Web前端JavaScript筆記繼承
- 好程式設計師web前端培訓分享JavaScript學習筆記ajax及ajax封裝程式設計師Web前端JavaScript筆記封裝
- 好程式設計師web前端培訓分享node學習筆記系列之四十一程式設計師Web前端筆記
- 好程式設計師web前端培訓學習筆記Vue學習筆記一程式設計師Web前端筆記Vue
- 好程式設計師web前端培訓分享詳解JavaScript學習筆記建構函式程式設計師Web前端JavaScript筆記函式
- 好程式設計師web前端培訓分享JavaScript框架J程式設計師Web前端JavaScript框架
- 好程式設計師web前端培訓分享之HTMLCSS學習筆記css3-多列程式設計師Web前端HTMLCSS筆記S3
- 好程式設計師web前端培訓學習筆記Vue學習筆記之二程式設計師Web前端筆記Vue
- 好程式設計師web前端培訓分享HTMLCSS學習之CSS基礎程式設計師Web前端HTMLCSS
- 好程式設計師web前端培訓分享之HTMLCSS學習筆記媒體查詢+ rem用法程式設計師Web前端HTMLCSS筆記REM
- 好程式設計師web前端教程分享JavaScript學習筆記之Event事件二程式設計師Web前端JavaScript筆記事件
- 好程式設計師web前端培訓分享怎樣學好css?程式設計師Web前端CSS
- 好程式設計師web前端培訓分享之uni-app學習筆記uni-app詳解程式設計師Web前端APP筆記
- 好程式設計師web前端培訓HTMLCSS學習筆記之頁面最佳化程式設計師Web前端HTMLCSS筆記
- 好程式設計師web前端培訓分享九個JavaScript小技巧程式設計師Web前端JavaScript
- 好程式設計師web前端培訓分享JavaScript基礎語法程式設計師Web前端JavaScript
- 好程式設計師web前端培訓分享JavaScript相關知識程式設計師Web前端JavaScript
- 好程式設計師web前端培訓分享Javascript中原型屬性程式設計師Web前端JavaScript原型
- 好程式設計師web前端培訓分享HTMLCSS學習筆記css3選擇器程式設計師Web前端HTMLCSS筆記S3