视察者形式
视察者形式在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的完成历程也使用了视察者形式。