本文摘自 《JavaScript 設(shè)計(jì)模式》張容銘 著 版權(quán)歸原作者所有
觀察者模式:又被稱作發(fā)布-訂閱者模式或消息機(jī)制,定義了一種依賴關(guān)系,解決了主體對象與觀察者之間功能的耦合
創(chuàng)建一個(gè)觀察者
// 將觀察者放在閉包中,當(dāng)頁面加載就立即執(zhí)行
var Observer = (function(){
// 防止消息隊(duì)列暴露而被篡改故將消息容器作為靜態(tài)私有變量保存
var _message = {};
return {
// 注冊信息接口
regist : function () {};
// 發(fā)布信息接口
fire : function () {};
// 移除信息接口
remove : function() {};
}
})();
實(shí)現(xiàn)消息注冊方法
regist : function () {
// 如果此消息不存在則應(yīng)該創(chuàng)建一個(gè)該消息類型
if(typeof _message[type] === 'undefined'){
// 將動(dòng)作推入到該消息對應(yīng)的動(dòng)作執(zhí)行隊(duì)列中
_message[type] = [fn];
// 如果此消息存在
}else{
// 將動(dòng)作方法推入該消息對應(yīng)的動(dòng)作執(zhí)行序列中
_message[type].push(fn);
}
}
定義發(fā)布消息的方法
fire : function(type,args){
// 如果該消息沒有被注冊,則返回
if(!_message[type]) return;
// 定義消息信息
var events = {
type : type, // 消息類型
args : args || {} // 消息攜帶數(shù)據(jù)
},
i = 0, // 消息動(dòng)作循環(huán)變量
len = _message[type].length; // 消息動(dòng)作長度
// 遍歷消息動(dòng)作
for(; i < len ; i ++) {
// 依次執(zhí)行注冊的消息對應(yīng)的動(dòng)作序列
_message[type][i].call(this,events);
}
}
消息注銷方法
remove : function (type,fn) {
// 如果消息動(dòng)作隊(duì)列存在
if(_message[type] instanceof Array) {
// 從最后一個(gè)消息動(dòng)作遍歷
var i = _message[type].length - 1;
for (; i >= 0 ; i--) {
// 如果存在該動(dòng)作則在消息動(dòng)作序列中移除相應(yīng)動(dòng)作
_message[type][i] === fn && _message[type].splice(i,1);
}
}
}
Observer.regist('test',function(e){
console.log(e.type,e.args.msg);
})
Observer.fire('test',{msg:'傳遞參數(shù)'}); // test 傳遞參數(shù)