中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久

Javascript設計模式之觀察者模式的多個實現版本實例
來源:易賢網 閱讀:1000 次 日期:2015-03-06 10:32:10
溫馨提示:易賢網小編為您整理了“Javascript設計模式之觀察者模式的多個實現版本實例”,方便廣大網友查閱!

這篇文章主要介紹了Javascript設計模式之觀察者模式的多個實現版本實例,本文給出3種實現版本代碼,同時給出了Jquery實現版本,需要的朋友可以參考下

介紹

觀察者模式又叫發布訂閱模式(Publish/Subscribe),它定義了一種一對多的關系,讓多個觀察者對象同時監聽某一個主題對象,這個主題對象的狀態發生變化時就會通知所有的觀察者對象,使得它們能夠自動更新自己。

使用觀察者模式的好處:

1.支持簡單的廣播通信,自動通知所有已經訂閱過的對象。

2.頁面載入后目標對象很容易與觀察者存在一種動態關聯,增加了靈活性。

3.目標對象與觀察者之間的抽象耦合關系能夠單獨擴展以及重用。

正文(版本一)

JS里對觀察者模式的實現是通過回調來實現的,我們來先定義一個pubsub對象,其內部包含了3個方法:訂閱、退訂、發布。

代碼如下:

var pubsub = {};

(function (q) {

var topics = {}, // 回調函數存放的數組

subUid = -1;

// 發布方法

q.publish = function (topic, args) {

if (!topics[topic]) {

return false;

}

setTimeout(function () {

var subscribers = topics[topic],

len = subscribers ? subscribers.length : 0;

while (len--) {

subscribers[len].func(topic, args);

}

}, 0);

return true;

};

//訂閱方法

q.subscribe = function (topic, func) {

if (!topics[topic]) {

topics[topic] = [];

}

var token = (++subUid).toString();

topics[topic].push({

token: token,

func: func

});

return token;

};

//退訂方法

q.unsubscribe = function (token) {

for (var m in topics) {

if (topics[m]) {

for (var i = 0, j = topics[m].length; i < j; i++) {

if (topics[m][i].token === token) {

topics[m].splice(i, 1);

return token;

}

}

}

}

return false;

};

} (pubsub));

使用方式如下:

代碼如下:

//來,訂閱一個

pubsub.subscribe('example1', function (topics, data) {

console.log(topics + ": " + data);

});

//發布通知

pubsub.publish('example1', 'hello world!');

pubsub.publish('example1', ['test', 'a', 'b', 'c']);

pubsub.publish('example1', [{ 'color': 'blue' }, { 'text': 'hello'}]);

怎么樣?用起來是不是很爽?但是這種方式有個問題,就是沒辦法退訂訂閱,要退訂的話必須指定退訂的名稱,所以我們再來一個版本:

代碼如下:

//將訂閱賦值給一個變量,以便退訂

var testSubscription = pubsub.subscribe('example1', function (topics, data) {

console.log(topics + ": " + data);

});

//發布通知

pubsub.publish('example1', 'hello world!');

pubsub.publish('example1', ['test', 'a', 'b', 'c']);

pubsub.publish('example1', [{ 'color': 'blue' }, { 'text': 'hello'}]);

//退訂

setTimeout(function () {

pubsub.unsubscribe(testSubscription);

}, 0);

//再發布一次,驗證一下是否還能夠輸出信息

pubsub.publish('example1', 'hello again! (this will fail)');

版本二

我們也可以利用原型的特性實現一個觀察者模式,代碼如下:

代碼如下:

function Observer() {

this.fns = [];

}

Observer.prototype = {

subscribe: function (fn) {

this.fns.push(fn);

},

unsubscribe: function (fn) {

this.fns = this.fns.filter(

function (el) {

if (el !== fn) {

return el;

}

}

);

},

update: function (o, thisObj) {

var scope = thisObj || window;

this.fns.forEach(

function (el) {

el.call(scope, o);

}

);

}

};

//測試

var o = new Observer;

var f1 = function (data) {

console.log('Robbin: ' + data + ', 趕緊干活了!');

};

var f2 = function (data) {

console.log('Randall: ' + data + ', 找他加點工資去!');

};

o.subscribe(f1);

o.subscribe(f2);

o.update("Tom回來了!")

//退訂f1

o.unsubscribe(f1);

//再來驗證

o.update("Tom回來了!");

如果提示找不到filter或者forEach函數,可能是因為你的瀏覽器還不夠新,暫時不支持新標準的函數,你可以使用如下方式自己定義:

代碼如下:

if (!Array.prototype.forEach) {

Array.prototype.forEach = function (fn, thisObj) {

var scope = thisObj || window;

for (var i = 0, j = this.length; i < j; ++i) {

fn.call(scope, this[i], i, this);

}

};

}

if (!Array.prototype.filter) {

Array.prototype.filter = function (fn, thisObj) {

var scope = thisObj || window;

var a = [];

for (var i = 0, j = this.length; i < j; ++i) {

if (!fn.call(scope, this[i], i, this)) {

continue;

}

a.push(this[i]);

}

return a;

};

}

版本三

如果想讓多個對象都具有觀察者發布訂閱的功能,我們可以定義一個通用的函數,然后將該函數的功能應用到需要觀察者功能的對象上,代碼如下:

代碼如下:

//通用代碼

var observer = {

//訂閱

addSubscriber: function (callback) {

this.subscribers[this.subscribers.length] = callback;

},

//退訂

removeSubscriber: function (callback) {

for (var i = 0; i < this.subscribers.length; i++) {

if (this.subscribers[i] === callback) {

delete (this.subscribers[i]);

}

}

},

//發布

publish: function (what) {

for (var i = 0; i < this.subscribers.length; i++) {

if (typeof this.subscribers[i] === 'function') {

this.subscribers[i](what);

}

}

},

// 將對象o具有觀察者功能

make: function (o) {

for (var i in this) {

o[i] = this[i];

o.subscribers = [];

}

}

};

然后訂閱2個對象blogger和user,使用observer.make方法將這2個對象具有觀察者功能,代碼如下:

代碼如下:

var blogger = {

recommend: function (id) {

var msg = 'dudu 推薦了的帖子:' + id;

this.publish(msg);

}

};

var user = {

vote: function (id) {

var msg = '有人投票了!ID=' + id;

this.publish(msg);

}

};

observer.make(blogger);

observer.make(user);

使用方法就比較簡單了,訂閱不同的回調函數,以便可以注冊到不同的觀察者對象里(也可以同時注冊到多個觀察者對象里):

復制代碼 代碼如下:

var tom = {

read: function (what) {

console.log('Tom看到了如下信息:' + what)

}

};

var mm = {

show: function (what) {

console.log('mm看到了如下信息:' + what)

}

};

// 訂閱

blogger.addSubscriber(tom.read);

blogger.addSubscriber(mm.show);

blogger.recommend(123); //調用發布

//退訂

blogger.removeSubscriber(mm.show);

blogger.recommend(456); //調用發布

//另外一個對象的訂閱

user.addSubscriber(mm.show);

user.vote(789); //調用發布

jQuery版本

根據jQuery1.7版新增的on/off功能,我們也可以定義jQuery版的觀察者:

代碼如下:

(function ($) {

var o = $({});

$.subscribe = function () {

o.on.apply(o, arguments);

};

$.unsubscribe = function () {

o.off.apply(o, arguments);

};

$.publish = function () {

o.trigger.apply(o, arguments);

};

} (jQuery));

調用方法比上面3個版本都簡單:

代碼如下:

//回調函數

function handle(e, a, b, c) {

// `e`是事件對象,不需要關注

console.log(a + b + c);

};

//訂閱

$.subscribe("/some/topic", handle);

//發布

$.publish("/some/topic", ["a", "b", "c"]); // 輸出abc

$.unsubscribe("/some/topic", handle); // 退訂

//訂閱

$.subscribe("/some/topic", function (e, a, b, c) {

console.log(a + b + c);

});

$.publish("/some/topic", ["a", "b", "c"]); // 輸出abc

//退訂(退訂使用的是/some/topic名稱,而不是回調函數哦,和版本一的例子不一樣

$.unsubscribe("/some/topic");

可以看到,他的訂閱和退訂使用的是字符串名稱,而不是回調函數名稱,所以即便傳入的是匿名函數,我們也是可以退訂的。

總結

觀察者的使用場合就是:當一個對象的改變需要同時改變其它對象,并且它不知道具體有多少對象需要改變的時候,就應該考慮使用觀察者模式。

總的來說,觀察者模式所做的工作就是在解耦,讓耦合的雙方都依賴于抽象,而不是依賴于具體。從而使得各自的變化都不會影響到另一邊的變化。

更多信息請查看IT技術專欄

更多信息請查看腳本欄目
由于各方面情況的不斷調整與變化,易賢網提供的所有考試信息和咨詢回復僅供參考,敬請考生以權威部門公布的正式信息和咨詢為準!

2026上岸·考公考編培訓報班

  • 報班類型
  • 姓名
  • 手機號
  • 驗證碼
關于我們 | 聯系我們 | 人才招聘 | 網站聲明 | 網站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點 | 投訴建議
工業和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網安備53010202001879號 人力資源服務許可證:(云)人服證字(2023)第0102001523號
云南網警備案專用圖標
聯系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關注公眾號:hfpxwx
咨詢QQ:1093837350(9:00—18:00)版權所有:易賢網
云南網警報警專用圖標
中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久
中日韩美女免费视频网站在线观看| 欧美日本乱大交xxxxx| 国产亚洲欧美一区在线观看 | 欧美国产日韩在线| 欧美午夜视频在线| 国产麻豆综合| 日韩一区二区精品葵司在线| 亚洲欧洲99久久| 欧美激情综合在线| 一区二区三区在线看| 亚洲视屏在线播放| 欧美69wwwcom| 国产在线精品自拍| 性做久久久久久免费观看欧美| 欧美大胆人体视频| 国产欧美日韩亚洲一区二区三区| 亚洲欧洲三级| 久久精品视频在线看| 国产精品二区三区四区| 亚洲美女在线看| 美日韩精品免费观看视频| 国产偷自视频区视频一区二区| 在线亚洲自拍| 欧美国产一区二区三区激情无套| 经典三级久久| 久久理论片午夜琪琪电影网| 国产女人精品视频| 亚洲欧美一区二区三区在线| 欧美日韩爆操| 99re66热这里只有精品3直播| 久久综合亚州| 精品白丝av| 久久久久久久一区二区| 国产日韩一区二区三区在线| 亚洲欧美日韩在线综合| 国产精品卡一卡二| 亚洲影院在线| 国产精品一区二区在线观看网站 | 国产农村妇女精品一区二区 | 国产精品老牛| 亚洲视频网在线直播| 欧美网站在线观看| 亚洲一区制服诱惑| 国产欧美精品一区二区三区介绍 | 国产欧美一区二区三区国产幕精品| aa成人免费视频| 欧美日韩国产影片| 亚洲一区在线看| 狠狠狠色丁香婷婷综合激情| 鲁鲁狠狠狠7777一区二区| 最近看过的日韩成人| 国产精品观看| 久久国产精品99精品国产| 一区在线观看视频| 欧美日韩一区二区视频在线| 亚洲欧美日韩在线| 黄色国产精品| 欧美激情精品久久久六区热门 | 欧美日韩卡一卡二| 在线亚洲免费| 国产偷国产偷亚洲高清97cao| 久久精品国产第一区二区三区最新章节 | 国产精品人成在线观看免费| 亚洲综合清纯丝袜自拍| 国产一区二区精品丝袜| 巨胸喷奶水www久久久免费动漫| 亚洲日本无吗高清不卡| 国产毛片精品国产一区二区三区| 久久躁日日躁aaaaxxxx| 99这里只有精品| 国产亚洲欧美一级| 欧美午夜电影一区| 理论片一区二区在线| 亚洲专区免费| 亚洲第一天堂无码专区| 国产精品色一区二区三区| 欧美国产成人在线| 久久精品中文| 午夜精品久久久久久 | 久久久人人人| 亚洲一区在线免费观看| 亚洲第一级黄色片| 欧美色大人视频| 欧美不卡视频一区发布| 性色av一区二区三区在线观看| 91久久国产精品91久久性色| 国产一区二区三区的电影| 国产精品久久久久一区二区三区| 欧美国产一区二区三区激情无套| 久久久久国产一区二区| 欧美在线电影| 亚洲欧美一区二区精品久久久| 91久久精品国产91久久性色tv | 久久蜜桃资源一区二区老牛| 亚洲欧美日韩直播| 亚洲一级片在线观看| 日韩视频久久| 99av国产精品欲麻豆| 亚洲精品乱码久久久久久| 亚洲国产成人在线视频| 亚洲国产精品第一区二区| 极品尤物av久久免费看| 永久久久久久| 亚洲大片一区二区三区| 亚洲成人在线| 亚洲欧洲日本专区| 亚洲精选视频免费看| 日韩一区二区精品视频| aa亚洲婷婷| 亚洲性夜色噜噜噜7777| 亚洲一区精品视频| 午夜精品福利一区二区蜜股av| 午夜欧美不卡精品aaaaa| 欧美尤物巨大精品爽| 亚洲欧美视频在线观看| 欧美专区在线观看| 欧美一区二区精美| 久久激情五月丁香伊人| 久久久亚洲影院你懂的| 久久男人资源视频| 欧美激情中文字幕一区二区| 欧美日韩一区二区三区免费看| 国产精品久久97| 国产精品视频你懂的| 国产视频欧美| 国产日产欧美a一级在线| 伊人春色精品| 一本色道久久综合亚洲精品高清| 亚洲天堂第二页| 久久久91精品| 欧美日韩成人免费| 国产色综合天天综合网| 亚洲电影免费观看高清完整版在线观看| 好看的av在线不卡观看| 亚洲欧洲精品成人久久奇米网| 中国成人亚色综合网站| 久久riav二区三区| 欧美日本在线| 国内激情久久| 一区二区三区视频观看| 欧美一区二区三区成人| 欧美大尺度在线| 国产精品视屏| 亚洲国产美女精品久久久久∴| 亚洲一区成人| 久久夜色精品国产| 欧美日韩中文字幕日韩欧美| 国产欧美精品在线| 日韩一级二级三级| 欧美一区二区在线观看| 欧美电影免费| 国语自产精品视频在线看8查询8| 日韩视频免费在线| 久久久久久9| 国产精品日韩欧美一区二区三区 | 国产一区二区三区在线播放免费观看| 原创国产精品91| 午夜欧美精品| 欧美午夜免费电影| 最新成人在线| 裸体歌舞表演一区二区| 国产亚洲成精品久久| 亚洲性视频h| 欧美肉体xxxx裸体137大胆| 亚洲国产裸拍裸体视频在线观看乱了| 亚洲欧美激情视频| 欧美午夜精品久久久久久久| 亚洲国产精品美女| 久久久久久婷| 精品69视频一区二区三区| 久久本道综合色狠狠五月| 国产欧美韩国高清| 午夜精品久久久久影视 | 久久se精品一区精品二区| 欧美日韩在线亚洲一区蜜芽| 亚洲乱码国产乱码精品精天堂| 久热精品视频在线观看| 永久免费视频成人| 久久香蕉国产线看观看av| 国内精品久久久久久久影视麻豆 | 欧美成人综合在线| 尤物视频一区二区| 久热精品视频在线| 亚洲高清一区二| 欧美成人精品| 夜夜狂射影院欧美极品| 欧美三级网页| 性久久久久久久久| 国产真实乱子伦精品视频| 欧美在线观看网址综合| 狠狠综合久久av一区二区小说| 久久婷婷国产麻豆91天堂| 亚洲韩国青草视频| 欧美日韩一区综合| 欧美亚洲一级| 亚洲黑丝一区二区| 欧美视频你懂的| 久久国产88| 亚洲巨乳在线| 国产日韩一区二区|