本回内容介绍
上一回,聊了门面模式,DOM2级事件,事件委托,介一回,也比较容易,代理模式(proxy),代理对象控制对本体对象的访问,实现了同样的接口,并且会把任何方法的调用传递到本体对象。
说白了,就是对访问进行控制。直接上代码,走你:
1.代理模式
代理也是对象,主要就是保护本体对象,对本体对象进行访问控制,本体对象有的,代理对象也有,如下:
// 定义一个房子的接口,可以租,可以卖,这里就只实现一个好了,保留租的方法:rent,有兴趣的可以扩展另一个
var House = new Interface("House",["sale"]);
// 买方
function Buyer(name){
this.name = name;
}
// 中介,也就是代理,这里传递的对象是买方对象
var Proxy = function(o){
// 买方名字
this.buyer = o.name;
// 业主实例
if(this.owner==null){
this.owner = new Owner(o);
}
// 验证接口
Interface.ensureImplements(this,House);
};
// 代理对象对本体对象的方法实现
Proxy.prototype = {
// 还原构造器
constructor:Proxy,
// 代理对象同样实现本体的方法
sale:function(money){
return this.owner.sale(money);
}
};
// 业主即本体,传递的对象依然是买方对象
var Owner = function(o){
this.buyer = o.name;
Interface.ensureImplements(this,House);
};
// 本体对象的方法实现
Owner.prototype = {
constructor:Owner,
// 本体对象的方法
sale:function(money){
return this.buyer+'支付了'+money+'万元买了别墅.';
}
};
var br = new Buyer('飞狐');
alert(new Proxy(br).sale('500')); // 飞狐支付了500万元买了别墅.
这个例子比较直观,买方,卖方,中介三种角色很好的诠释了代理模式,也比较好理解,看下一个例子,走你.
2. 虚拟代理
这里聊一个虚拟代理,就是在代理的方法被调用的时候再去实例化相关的对象。还记得之前的惰性单例模式么,虚拟代理有点类似,看例子:
// 定义一个年级
var Grades = function(){};
Grades.prototype = {
// 检测人数
check:function(o){
alert(o.length+"人");
}
};
// 年级代理
var GradesProxy = function() {
// 先不初始化Grades.
this.gra = null;
};
GradesProxy.prototype = {
// 这里就是按需初始化
init: function() {
if (!this.gra) {
this.gra = new Grades();
}
},
// 检测学生人数
check: function(s) {
// 调用 init()
this.init();
return this.gra.check(s);
}
}
// 测试
var students = ['大卫','撸壕','飞狐'];
var o = new GradesProxy();
o.check(students); //3人
这个例子比较简单,没有写太多方法,也没有单独写学生类,用一个数组一笔带过,目的是更直观的展示在用时初始化本体对象。
惯例性装逼,今天看新闻,钟汉良导演,韩寒监制的新片《沙漏》,继《后会无期》后又一次合作,期待啊~~
这一回聊的内容少,难度很小,比较好理解。
下面的内容来一个实例,懒加载,懒加载是代理模式很好的一个实践。
JS图片懒加载
懒加载又叫延迟加载,通过自定义属性,把真实的img地址存到自定义属性中,如:data-url=”img”,而图片真正的src存的是loading的图片,如src=”loading.gif”,当拖动滚动条发生窗口的偏移,再动态将data-url的值赋给src; 实时的替换img的src的图片路径,绕么,看例子吧:
// 这里是html的代码,
<ul>
<li><img src="./img/loading.gif" data-url="./img/1.jpg"/></li>
<li><img src="./img/loading.gif" data-url="./img/2.jpg"/></li>
<li><img src="./img/loading.gif" data-url="./img/3.jpg"/></li>
<li><img src="./img/loading.gif" data-url="./img/4.jpg"/></li>
<li><img src="./img/loading.gif" data-url="./img/5.jpg"/></li>
<li><img src="./img/loading.gif" data-url="./img/6.jpg"/></li>
</ul>// ...省略很多的图片
// 这里开始是js代码,没有写script,只是简单的模拟
function $(t){
return document.getElementsByTagName(t);
}
// 获取id
function lazyLoad(el) {
// 遍历需要加载的图片元素
for (var i = 0, len = el.length; i < len; i++) {
// 根据class属性判断是否已经加载过
if (el[i].className != "load") {
// 这里就是获取data-url的值,也就是真实图片路径,替代loading图片
el[i].src = el[i].getAttribute("data-url");
// 替代后加一个class属性已经加载过的标记
el[i].className = "load";
}
}
};
// 滚动时执行
window.onscroll = function() {
lazyLoad($("img"));
};
// 加载后执行
window.onload = function() {
lazyLoad($("img"));
};
这里只是简单的模拟,代码量少,应该可以很容易看懂,懒加载运用比较广泛,可以提高性能,京东首页目前也是这么做的。
这一回,主要聊了代理模式,虚拟代理,图片懒加载,难度适中~~
下一回,聊一下适配器模式,难度也比较小。
客观看完点个赞,推荐推荐呗,嘿嘿~~
注:此系飞狐原创,转载请注明出处
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。