代理模式是为了一个对象提供一个代用品或占位符,以便控制对它的访问。对象本身是本体对象,代用品则是代理对象。当客户不方便直接访问一个对象或者不满足需要的时候提供一个替身对象来控制对这个对象的访问,客户实际上访问的是代理对象,最终代理对象内部访问本体对象。
代理对象和本体对象的接口要保持一致性,在用户看来本体和代理体是一致的,是透明的才行。
一、虚拟代理
虚拟代理:是将本体对象的方法进行管理,等到本体对象合适的时候再通过代理对象执行本体对象的方法。
优点:将开销很大的对象,延迟到真正需要本体对象的时候再执行本体对象的方法,可以提高Web前端性能。
应用场景:
1、虚拟代理实现图片预加载
当我们请求一个很大的图片的时候,可能图片加载很慢,为了提升用户体验,需提前加载到本地缓存。那么我们可以先使用一张占位图片,当图片加载完毕,再指向本体函数设置真实的图片路径。
var myImage =(function(){
var imgNode =document.createElement('img');
document.body.appendChild(imgNode);
return {
setSrc:function(src){
imgNode.src=src;
}
}
}())
// 代理负责预加载图片,预加载的操作完成之后,将重新请求交给本体的myImage.
var proxyImage = (function(){
var img= new Image();
//1、ready 是 DOM 加载完成的事件
// 2、onload 是所有内容加载完成(如:图片)自动触发的时间
img.onload=function(){
myImage.setSrc(this.src); //this指向img
}
return{
setSrc:function(src){
myImage.setSrc('///loding.png');
img.src=src;
}
}
})()
2、虚拟代理实现合并http请求
如果对于实时条件不那么严格的业务中,可以先访问代理对象将数据保存起来,等一段时间代理对象再将所有的数据一起发送给本体对象。这样就不要一个一个发送请求,避免不断的发送http请求消耗性能。
var proxySyn=(function(){
var cache=[]; //用来存放数据.
var timer;
return function(id,fn){
cache.push(id); //将条件保存起来
if(timer) return; //保证不会覆盖已经启动的定时器
timer=setTimeout(function(){
fn(cache.join(',')); //执行函数
clearTimeout(timer);
timer=null;
cache.length=0;
},2000) //过2m再发送
}
}())
3、虚拟代理在懒加载
等到真正需要的时候才触发本体函数。关键在于运用一个列表将内容进行存储,等到真正需要的时候再执行内容。
var miniConsole =(function(){
var cache=[];
var handler=function(ev){
if(ev.keyCode===113){ //做什么动作的时候才真正加载
var script=document.createElement('script');
script.onload=function(){
for(var i=0,fn;fn=cache[i++];){
fn()
}
};
script.src='miniConsole.js';
document.getElementsByTagName('head')[0].appendChild(script);
document.body.removeEventListener('keydown',handler); //只加载一次miniConsole.js
}
};
document.body.addEventListener('keydown',handler,false);
return {
log:function(){ //还没真正的加载
var args=arguments;
cache.push(function(){
return miniConsole.log.apply(miniConsole,args)
})
}
}
}());
miniConsole={
log:function(){
console.log('执行')
}
}
二、缓存代理
缓存代理:将一些条件相同的请求,请求回来的数据做缓存。等下次再请求时,直接返回即可。
优点:减少http的请求,避免大量重复的计算。
应用场景:
1、分页请求数据
var proxyMult=(function(){
var cache={}; //用一个值来保存数据
return function(){
var args=Array.prototype.join.call(arguments,',');
if(args in cache){
return cache[args];
}
var callback=function(data){
return cache[args]=data;
}
mult.call(this,arguments,callback)
// return cache[args]=mult.apply(this,arguments); //同步情况
}
})()
4、
var proxy=(function(){
var cache=[];
return function(){
var args=arguments;
cache.push(function(){
return fn.apply(fn,args)
})
return cache;
}
}())
三、保护代理
保护代理:主要用于控制不同权限的对象对本体对象的访问权限。
优点:将来访的对象通过代理对像进行过滤,满足要求再指向本体对象。