观察者模式
观察者模式在JS的学习过程中很重要,尤其是最近几年MV*框架的发展。
观察者模式很好的体现了松耦合(Loose coupling)原则和单一职责原则。
观察者模式
它定义了对象间一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都将得到通知。
观察者模式由主体和观察者组成,主体负责发布事件,观察者通过订阅事件来观察主体。
主体并不知道观察者的任何事情,观察者知道主体并能注册事件的回调函数。
代码1:
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的实现过程也使用了观察者模式。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。