觀察者模式在JS的學習過程當中很重要,尤爲是最近幾年MV*框架的發展。
觀察者模式很好的體現了鬆耦合(Loose coupling)原則和單一職責原則。
觀察者模式
它定義了對象間一種一對多的依賴關係,當一個對象的狀態發生改變時,全部依賴它的對象都將獲得通知。
觀察者模式由主體和觀察者組成,主體負責發佈事件,觀察者經過訂閱事件來觀察主體。
主體並不知道觀察者的任何事情,觀察者知道主體並能註冊事件的回調函數。angularjs
代碼1:es6
function Emitter(){ this._listerner={};//自定義事件名 } Emitter.prototype.bind=function(eventName,handler){ // var listenersArr=this._listerner[eventName]||[]; // listenersArr.push(handler); // this._listerner[eventName]=listenersArr; if(!this._listerner.hasOwnProperty(eventName)){ this._listerner[eventName]=[]; } this._listerner[eventName].push(handler); } Emitter.prototype.trigger=function(eventName){ if (!this._listerner.hasOwnProperty(eventName)) { console.log('你沒綁定這個事件'); return; } var args = Array.prototype.slice.call(arguments, 1); ////args爲得到除了eventName後面的參數(最後被用做註冊事件的參數) //arguments並非真正的數組對象,只是與數組相似而已,因此它並無slice這個方法 //Array.prototype.slice.call(arguments, 1)能夠理解成是讓arguments轉換成一個數組對象,讓arguments具備slice()方法。 //要是直接寫arguments.slice(1)會報錯 this._listerner[eventName].forEach(function(callback){ callback.call(this,args);//經過這種方法能夠傳參 }); } function handler1(){ console.log('第一次綁定'); //console.log(arguments); Array.prototype.forEach.call(arguments,function(item){//arguments.forEach(function(item)),arguments爲上面trigger中調用它時傳進來的參數 console.log(item); }) } function handler2(){ console.log('第二次綁定'); } function handler3(){ console.log('第三次綁定'); } var emitter=new Emitter(); emitter.bind('selfEvent',handler1); emitter.bind('selfEvent',handler2); emitter.bind('selfEvent2',handler3); emitter.trigger('selfEvent',233333333);
代碼2(下面這段來自stackoverflow):設計模式
//model function Book(name,isbn){ this.name=name; this.isbn=isbn; } function BookCollection(books){ this.books=books; } BookCollection.prototype.addBook=function(book){ this.books.push(book); $.publish('book-added',book); return book; } BookCollection.prototype.removeBook=function(book){ var removed; if(typeof book==='number'){ removed=this.books.splice(book,1); } for(var i=0;i<this.books.length;i+=1){ if(this.books[i]===book){ removed=this.books.splice(i,1); } } $.publish('book-removed',removed); return removed; } //View var BookListView=(function(){ function removeBook(book){ $('#'+book.isbn).remove(); } function addBook(book){ $(#bookList).append('<div id="'+book.isbn+'">'+book.name+'</div>'); } return { init:function(){ $.subscribe('book-removed',removeBook); $.subscribe('book-added',addBook); } } }());
應用:
1) angularjs的雙向數據綁定中,就涉及到了這個設計模式。
angularjs的雙向數據綁定主要是利用髒檢查來完成的。可是如何把一個model綁定到多個view就是利用觀察者模式來作的。數組
2)es6中的Promise的實現過程也使用了觀察者模式。app