链模式(OperateOfResponsibility)
核心
- 定义:在对象方法中将当前对象返回,实现对一个对象多个方法的链式调用
- 重点:简化接口调用(返回 this )
- 应用:jQuery 方法链式调用
示例一:jQuery 获取元素功能
- 需求:简单模拟 jQuery 获取元素的基本功能
- js
var A = function (selector, context) {
return new A.fn.init(selector, context);
};
A.fn = A.prototype = {
init: function (selector, context = document) {
this.length = 0;
if (~selector.indexOf("#")) {
this[0] = document.getElementById(selector.slice(1));
this.length = 1;
} else {
var doms = context.getElementsByTagName(selector),
i = 0,
len = doms.length;
for (; i < len; i++) {
this[i] = doms[i];
}
this.length = len;
}
this.context = context;
this.selector = selector;
return this;
},
size() {
return this.length;
},
splice: [].splice,
};
A.fn.init.prototype = A.fn;
console.log(A("#d1"));
console.log(A("#d1").size());
console.log(A("div", A("#d1")[0]).size());
if (typeof module !== "undefined") {
module.exports = A;
}
<div id="d1">
<div>11</div>
<div></div>
<div></div>
</div>
- 效果
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210419103740322.png)
示例二:jQuery 方法拓展
- 需求:实现 jQuery 的 extend 方法(内部/外部对象拓展)
- js
if (typeof require === "function") {
A = require("./index");
}
A.extend = A.fn.extend = function () {
let i = 1,
len = arguments.length,
target = arguments[0],
j;
if (len === 1) {
target = this;
i--;
}
for (; i < len; i++) {
for (j in arguments[i]) {
target[j] = arguments[i][j];
}
}
return target;
};
var obj = {
};
console.log(A.extend(obj, {
a: 1, b: 2 }, {
a: 2, c: 3 }) === obj);
console.log(obj);
A.fn.extend(obj, {
d: 4, b: 0 });
console.log(obj);
if (typeof window === "object") {
A.extend(A.fn, {
version: "1.0" });
const d1 = A("#d1");
console.log(d1);
console.log(d1.version);
A.fn.extend({
getVersion() {
return this.version;
},
});
console.log(d1.getVersion());
A.extend({
a: 11, b: 22 });
A.extend({
c: 33 });
const {
a, b, c } = A;
console.log(a, b, c);
}
示例三:jQuery 操作 DOM 方法
- 需求:模拟 jQuery ,实现 事件绑定,html / css / attr 查询和赋值
- js
A.extend({
camelCase(str) {
return str.replace(/\-(\w)/g, function (all, letter) {
console.log(all, letter);
return letter.toUpperCase();
});
},
});
A.fn.extend({
on: (function () {
if (document.addEventListener) {
return function (type, fn) {
for (var i = 0; i < this.length; i++) {
this[i].addEventListener(type, fn, false);
}
return this;
};
}
else if (document.attachEvent) {
return function (type, fn) {
for (var i = 0; i < this.length; i++) {
this[i].attachEvent(`on${
type}`, fn);
}
return this;
};
}
else {
return function (type, fn) {
for (var i = 0; i < this.length; i++) {
this[i][`on${
type}`] = fn;
}
return this;
};
}
})(),
css() {
const args = arguments,
len = args.length;
if (this.length < 1) return this;
if (len === 1) {
if (typeof args[0] === "string") {
return getComputedStyle(this[0])[A.camelCase(args[0])];
}
else if (typeof args[0] === "object" && args[0] !== null) {
for (var i in args[0]) {
for (var j = 0; j < this.length; j++) {
this[j].style[A.camelCase(i)] = args[0][i];
}
}