本文深入解析 JavaScript 中的职责链模式,阐述其如何解耦请求发送者与接收者。通过对比链表结构,明确职责链可在任意节点发起的特性。文章结合 DOM 事件冒泡机制,利用原型链构建 CreateDOM 类,演示如何模拟 li、ul、div 的对象链式调用,并重点讲解通过覆盖原型方法并显式调用父级 handle 来实现链式传递的具体代码实现。
职责链模式概述
一、概述
职责链模式(Chain of responsibility)旨在让多个对象都有机会处理请求,从而消除请求发送者与接收者之间的耦合关系。这些对象被连接成一条链,请求沿着这条链传递,直到有对象处理它为止。
这种结构在外观上看似与数据结构中的链表相似。
然而,两者存在本质区别:职责链允许从链中的任意节点开始向下查找处理者,而链表必须从头节点开始遍历。
例如,DOM 事件机制中的冒泡过程符合职责链的特征,而捕获阶段则更接近链表的结构。
利用职责链模拟 DOM 冒泡
二、利用职责链模拟冒泡
假设存在三个对象:li、ul 和 div,它们的关系结构如下:

当触发 li 对象时,若 li 未阻止冒泡,请求将传递给 ul;若 ul 也未阻止,则继续传递给 div(假设 div 为根节点)。ul 和 div 的处理逻辑同理。
由此可见,职责链模式非常适合实现此类需求。
那么,如何使用 JavaScript 实现职责链模式呢?
我们可以通过原型链来构建基本架构,如下所示:
function CreateDOM(obj){
this.next = obj || null;
};
CreateDOM.prototype = {
handle: function(){
if(this.next){
this.next.handle();
}
}
};
每次使用 CreateDOM 构造函数创建对象时,都将与之关联的下一个对象作为参数传入(这看起来很像链表结构)。
随后,当触发某个对象并执行 handle 方法时,请求即可沿着这条链向下传递。
需要注意的是,如果某个对象的 handle 属性覆盖了原型链中的 handle 方法,如何确保请求继续向下传递?
只需在覆盖的方法中调用 CreateDOM.prototype.handle.call(this) 即可实现链式传递。
以下是实现 li、ul 和 div 的具体代码:
var li = null,
ul = null,
div = null;
div = new CreateDOM();
div.handle = function(stopBubble){
console.log('DIV');
if(stopBubble){
return;
}else{
CreateDOM.prototype.handle.call(this);
}
};
ul = new CreateDOM(div);
ul.handle = function(stopBubble){
console.log('UL');
if(stopBubble){
return;
}else{
CreateDOM.prototype.handle.call(this);
}
};
li = new CreateDOM(ul);
li.handle = function(stopBubble){
console.log('LI');
if(stopBubble){
return;
}else{
CreateDOM.prototype.handle.call(this);
}
};
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。