免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
深入理解JavaScript系列(38):設(shè)計(jì)模式之職責(zé)鏈模式

介紹

職責(zé)鏈模式(Chain of responsibility)是使多個(gè)對(duì)象都有機(jī)會(huì)處理請(qǐng)求,從而避免請(qǐng)求的發(fā)送者和接受者之間的耦合關(guān)系。將這個(gè)對(duì)象連成一條鏈,并沿著這條鏈傳遞該請(qǐng)求,直到有一個(gè)對(duì)象處理他為止。

也就是說,請(qǐng)求以后,從第一個(gè)對(duì)象開始,鏈中收到請(qǐng)求的對(duì)象要么親自處理它,要么轉(zhuǎn)發(fā)給鏈中的下一個(gè)候選者。提交請(qǐng)求的對(duì)象并不明確知道哪一個(gè)對(duì)象將會(huì)處理它——也就是該請(qǐng)求有一個(gè)隱式的接受者(implicit receiver)。根據(jù)運(yùn)行時(shí)刻,任一候選者都可以響應(yīng)相應(yīng)的請(qǐng)求,候選者的數(shù)目是任意的,你可以在運(yùn)行時(shí)刻決定哪些候選者參與到鏈中。

正文

對(duì)于JavaScript實(shí)現(xiàn),我們可以利用其原型特性來實(shí)現(xiàn)職責(zé)鏈模式。

var NO_TOPIC = -1;
var Topic;

function Handler(s, t) {
this.successor = s || null;
this.topic = t || 0;
}

Handler.prototype = {
handle: function () {
if (this.successor) {
this.successor.handle()
}
},
has: function () {
return this.topic != NO_TOPIC;
}
};

Handler只是接受2個(gè)參數(shù),第一個(gè)是繼任者(用于將處理請(qǐng)求傳下去),第二個(gè)是傳遞層級(jí)(可以用于控制在某個(gè)層級(jí)下是否執(zhí)行某個(gè)操作,也可以不用),Handler原型暴露了一個(gè)handle方法,這是實(shí)現(xiàn)該模式的重點(diǎn),先來看看如何使用上述代碼。

    var app = new Handler({
handle: function () {
console.log('app handle');
}
}, 3);

var dialog = new Handler(app, 1);

var button = new Handler(dialog, 2);

button.handle();

改代碼通過原型特性,調(diào)用代碼從button.handle()->dialog.handle()->app.handle()->參數(shù)里的handle(),前三個(gè)都是調(diào)用原型的handle,最后才查找到傳入的參數(shù)里的handle,然后輸出結(jié)果,也就是說其實(shí)只有最后一層才處理。

那如何做到調(diào)用的時(shí)候,只讓dialog的這個(gè)對(duì)象進(jìn)行處理呢?其實(shí)可以定義dialog實(shí)例對(duì)象的handle方法就可以了,但需要在new button的之前來做,代碼如下:

    var app = new Handler({
handle: function () {
console.log('app handle');
}
}, 3);

var dialog = new Handler(app, 1);
dialog.handle = function () {
console.log('dialog before ...')
// 這里做具體的處理操作
console.log('dialog after ...')
};

var button = new Handler(dialog, 2);

button.handle();

該代碼的執(zhí)行結(jié)果即時(shí)dialog.handle里的處理結(jié)果,而不再是給app傳入的參數(shù)里定義的handle的執(zhí)行操作。

那能不能做到自身處理完以后,然后在讓繼任者繼續(xù)處理呢?答案是肯定的,但是在調(diào)用的handle以后,需要利用原型的特性調(diào)用如下代碼:

Handler.prototype.handle.call(this);

該句話的意思說,調(diào)用原型的handle方法,來繼續(xù)調(diào)用其繼任者(也就是successor )的handle方法,以下代碼表現(xiàn)為:button/dialog/app三個(gè)對(duì)象定義的handle都會(huì)執(zhí)行。

var app = new Handler({
handle: function () {
console.log('app handle');
}
}, 3);

var dialog = new Handler(app, 1);
dialog.handle = function () {
console.log('dialog before ...')
// 這里做具體的處理操作
Handler.prototype.handle.call(this); //繼續(xù)往上走
console.log('dialog after ...')
};

var button = new Handler(dialog, 2);
button.handle = function () {
console.log('button before ...')
// 這里做具體的處理操作
Handler.prototype.handle.call(this);
console.log('button after ...')
};

button.handle();

通過代碼的運(yùn)行結(jié)果我們可以看出,如果想先自身處理,然后再調(diào)用繼任者處理的話,就在末尾執(zhí)行Handler.prototype.handle.call(this);代碼,如果想先處理繼任者的代碼,就在開頭執(zhí)行Handler.prototype.handle.call(this);代碼。

總結(jié)

職責(zé)鏈模式經(jīng)常和組合模式一起使用,這樣一個(gè)構(gòu)件的父構(gòu)件可以作為其繼任者。

同時(shí),DOM里的事件冒泡機(jī)制也和此好像有點(diǎn)類似,比如點(diǎn)擊一個(gè)按鈕以后,如果不阻止冒泡,其click事件將一直向父元素冒泡,利用這個(gè)機(jī)制也可以處理很多相關(guān)的問題,比如本系列設(shè)計(jì)模式享元模式里的《例1:事件集中管理》的示例代碼。

參考代碼:https://gist.github.com/1174982

同步與推薦

本文已同步至目錄索引:深入理解JavaScript系列

深入理解JavaScript系列文章,包括了原創(chuàng),翻譯,轉(zhuǎn)載等各類型的文章,如果對(duì)你有用,請(qǐng)推薦支持一把,給大叔寫作的動(dòng)力。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
RPC 技術(shù)及其框架 Sekiro 在爬蟲逆向中的應(yīng)用,加密數(shù)據(jù)一把梭!
JS學(xué)習(xí)
玩轉(zhuǎn) JS 逆向:RPC 加持,爬蟲效率飆升
JavaScript自定義事件介紹
Javascript開發(fā)經(jīng)驗(yàn)談(轉(zhuǎn))
前端基礎(chǔ)進(jìn)階(十三):透徹掌握Promise的使用,讀這篇就夠了
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服