代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问。
分类:
1. 保护代理: 代理可以为实际需要进行的操作过滤掉一些请求。
2. 虚拟代理: 把一些开销很大的对象,延迟到真正需要它的时候才去创建。
应用:1. 虚拟代理实现图片预加载
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' );
应用2: 虚拟代理合并HTTP请求
var synchronousFile = function( id ){ console.log( '开始同步文件,id 为: ' + id ); }; var proxySynchronousFile = (function(){ var cache = [], // 保存一段时间内需要同步的ID timer; // 定时器 return function( id ){ cache.push( id ); if ( timer ){ // 保证不会覆盖已经启动的定时器 return; } timer = setTimeout(function(){ synchronousFile( cache.join( ',' ) ); // 2 秒后向本体发送需要同步的ID 集合 clearTimeout( timer ); // 清空定时器 timer = null; cache.length = 0; // 清空ID 集合 }, 2000 ); } })(); var checkbox = document.getElementsByTagName( 'input' ); for ( var i = 0, c; c = checkbox[ i++ ]; ){ c.onclick = function(){ if ( this.checked === true ){ proxySynchronousFile( this.id ); } } };
应用三: 惰性加载中的使用
三: 缓存代理
应用一: 为加减乘除创建缓存代理
/**************** 计算乘积 *****************/ var mult = function(){ var a = 1; for ( var i = 0, l = arguments.length; i < l; i++ ){ a = a * arguments[i]; } return a; }; /**************** 计算加和 *****************/ var plus = function(){ var a = 0; for ( var i = 0, l = arguments.length; i < l; i++ ){ a = a + arguments[i]; } return a; }; /**************** 创建缓存代理的工厂 *****************/ var createProxyFactory = function( fn ){ var cache = {}; return function(){ var args = Array.prototype.join.call( arguments, ',' ); if ( args in cache ){ return cache[ args ]; } return cache[ args ] = fn.apply( this, arguments ); } }; var proxyMult = createProxyFactory( mult ), proxyPlus = createProxyFactory( plus ); alert ( proxyMult( 1, 2, 3, 4 ) ); // 输出:24 alert ( proxyMult( 1, 2, 3, 4 ) ); // 输出:24 alert ( proxyPlus( 1, 2, 3, 4 ) ); // 输出:10 alert ( proxyPlus( 1, 2, 3, 4 ) ); // 输出:10
应用二: 缓存代理用于ajax异步请求数据
我们在常常在项目中遇到分页的需求,同一页的数据理论上只需要去后台拉取一次,这些已经拉取到的数据在某个地方被缓存之后,下次再请求同一页的时候,便可以直接使用之前的数据。显然这里也可以引入缓存代理,实现方式跟计算乘积的例子差不多,唯一不同的是,请求数据是个异步的操作,我们无法直接把计算结果放到代理对象的缓存中,而是要通过回调的方式。