代理模式是一种对程序对象进行控制性访问的一类解决方案。
引入代理模式,其实是为了实现单一职责的面向对象设计原则。
单一职责其实就是指在一个类中(js中通常指对象和函数等),应仅有一个引起它变化的原因。这样会帮助程序设计具有良好的健壮和高内聚特性,从而当变化发生时,程序设计会尽量少的受到意外破坏。
代理模式有多种方法,保护代理、远程代理、虚拟代理、缓存代理等。
但在javascript中,代理模式最常用到的两种方法是虚拟代理和缓存代理。
虚拟代理
在理解虚拟代理时,可以将其想象为一个经纪人,客户程序需要通过这个虚拟代理(经纪人)来调用本体对象的方法。
虚拟代理示例demo1: 图片loading预加载
//通过虚拟代理实现图片预加载//代理模式进行图片预加载的实现思路是: 通过代理对象获取实际显示图片地址并进行加载,同时先让本体对象显示预加载图片,待代理对象将实际图片地址加载完毕后传递给本体对象进行显示即可。//本体对象var myImage = (function(){ var imgNode = new Image() document.body.appendChild(imgNode) return { setSrc: function(src){ imgNode.src = src } }})()//代理对象var proxyImage = (function(){ var img = new Image(); //1、代理对象新建一个img对象 img.onload = function(){ //4、代理对象img加载真实图片src完成后将src传递给本体对象显示 myImage.setSrc(this.src) } return { setProxySrc: function(src){ myImage.setSrc('../images/loding.gif') //2、代理对象控制本体对象使用加载图片src img.src = src //3、代理对象的img对象获取将要传递给本体对象的真实图片src } }})()//通过代理对象来对本体对象进行访问proxyImage.setProxySrc('https://p1.ssl.qhimgs1.com/t0153297036f4471d81.jpg')
虚拟代理示例demo2:合并HTTP请求,减少网络请求资源消耗
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>代理模式 虚拟代理合并HTTP请求</title></head><body> <div> <input type="checkbox" id="1" />1 <input type="checkbox" id="2" />2 <input type="checkbox" id="3" />3 <input type="checkbox" id="4" />4 <input type="checkbox" id="5" />5 <input type="checkbox" id="6" />6 <input type="checkbox" id="7" />7 <input type="checkbox" id="8" />8 <input type="checkbox" id="9" />9 </div> </body><script> //使用 //本体对象 var synchornurFile = function(id){ console.log('开始同步:' + id); } var proxySynchornurFile = (function(){ var cache = [], //集合一段时间内需要同步的id timer; //定时器 return function(id){ cache.push(id) if(timer){ //保证不会覆盖已经启动的定时器 return } timer = setTimeout(function(){ synchornurFile(cache.join(',')) clearTimeout(timer) timer = null cache.length = 0 }, 2000) } })() var check = document.getElementsByTagName('input') for(var i=0; i<check.length; i++){ check[i].onclick = function(){ if(this.checked === true){ proxySynchornurFile(this.id) } } }</script></html>
新闻热点
疑难解答
图片精选