js 设计模式
代理模式
代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问。
例子:
实现图片预加载:在 Web 开发中,图片预加载是一种常用的技术,如果直接给某个 img 标签节点设置 src 属性, 由于图片过大或者网络不佳,图片的位置往往有段时间会是一片空白,可以先用一张 loading 图片占位,然后用异步的方式加载图片,等图片加载好了再把它填充到 img 节点里:
不使用代理:
var MyImage = (function () {
var imgNode = document.createElement('img');
document.body.appendChild(imgNode);
var img = new Image();
img.onload = function () {
imgNode.src = img.src;
};
return {
setSrc: function (src) {
imgNode.src = 'file:// /C:/Users/svenzeng/Desktop/loading.gif';
img.src = src;
},
};
})();
MyImage.setSrc('http:// imgcache.qq.com/music/photo/k/000GGDys0yA0Nk.jpg');
使用代理
var myImage = (function () {
var imgNode = document.createElement('img'); document.body.appendChild(imgNode);
return {
setSrc: function (src) {
imgNode.src = src;
}
}
})();
var proxyImage = (function () {
var img = new Image; img.onload = function () {
myImage.setSrc(this.src);
}
return {
setSrc: function (src) {
myImage.setSrc('file:// /C:/Users/svenzeng/Desktop/loading.gif');
img.src = src;
}
}
})();
proxyImage.setSrc('http:// imgcache.qq.com/music/photo/k/000GGDys0yA0Nk.jpg');
现在我们通过 proxyImage 间接地访问 MyImage。proxyImage 控制了客户对 MyImage 的访问,并 且在此过程中加入一些额外的操作,比如在真正的图片加载好之前,先把 img 节点的 src 设置为 一张本地的 loading 图片。
代理的意义
维护单一职责
单一职责原则指的是,就一个类(通常也包括对象和函数等)而言,应该仅有一个引起它变 化的原因。如果一个对象承担了多项职责,就意味着这个对象将变得巨大,引起它变化的原因可 能会有多个。
面向对象设计鼓励将行为分布到细粒度的对象之中,如果一个对象承担的职责过多, 等于把这些职责耦合到了一起,这种耦合会导致脆弱和低内聚的设计。当变化发生时,设计可能 会遭到意外的破坏。
迭代器模式
迭代器模式是指提供一个方法可以顺序访问一个聚合对象的各个元素,而又不用暴露对象的内部表示。
大部分语言都已经实现迭代器。在 js 比较有用的是提供访问类数组的方法:
// 在 JavaScript 中,for in 语句可以用来迭代普通字面量对象的属性。jQuery 中提供了$.each` 函数来封装各种迭代行为:
$.each = function (obj, callback) {
var value,
i = 0,
length = obj.length,
isArray = isArraylike(obj);
if (isArray) { // 迭代类数组 for ( ; i < length; i++ ) {
value = callback.call(obj[i], i, obj[i]);
if (value === false) {
break;
}
}
} else {
for (i in obj) { // 迭代object对象
value = callback.call(obj[i], i, obj[i]); if (value === false) {
break;
}
}
}
return obj; };
发布订阅模式
发布—订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状 态发生改变时,所有依赖于它的对象都将得到通知。在 JavaScript 开发中,我们一般用事件模型 来替代传统的发布—订阅模式。
扩展:
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1249118795@qq.com