一、简单的单例模式:

1、未使用代理模式的情况:小明直接给女神送花

复制代码
var Flower = function() {} var xiaoming = {   sendFlower: function( target ){     var flower = new Flower();     target.receiveFlower( flower );    } }; var A = {   receiveFlower: function( flower ){     console.log( '收到花 ' , flower );    } }; xiaoming.sendFlower( A );
复制代码

2、使用简单的代理模式:小明

复制代码
var Flower = function() {} var xiaoming = {   sendFlower: function( target ){     var flower = new Flower();     target.receiveFlower( flower );    } }; var A = {   receiveFlower: function( flower ){     console.log( '收到花 ' , flower );    } }; var B = {     receiveFlower: function( flower ){       A.receiveFlower(flower)     } } xiaoming.sendFlower( B );
复制代码

二、保护代理和虚拟代理

虽然这只是个虚拟的例子,但我们可以从中找到两种代理模式的身影。代理 B 可以帮助 A 过滤掉一些请求,比如送花的人中年龄太大的或者没有宝马的,这种请求就可以直接在代理 B 处被拒绝掉。这种代理叫作保护代理。A 和 B 一个充当白脸,一个充当黑脸。白脸 A 继续保持 良好的女神形象,不希望直接拒绝任何人,于是找了黑脸 B 来控制对 A 的访问。

另外,假设现实中的花价格不菲,导致在程序世界里,new Flower 也是一个代价昂贵的操作, 那么我们可以把 new Flower 的操作交给代理 B 去执行,代理 B 会选择在 A 心情好时再执行 new Flower,这是代理模式的另一种形式,叫作虚拟代理。虚拟代理把一些开销很大的对象,延迟到 真正需要它的时候才去创建。

三、虚拟代理实现图片预加载

复制代码
var myImage = (function(){   var imgNode = document.createElement( 'img' );    document.body.appendChild( imgNode );   return {     setSrc: function( src ){       imgNode.src = src;      }   }  })(); myImage.setSrc('http:// imgcache.qq.com/music/photo/k/000GGDys0yA0Nk.jpg');
复制代码
普通方式下,我们把网速调至 5KB/s,然后通过 MyImage.setSrc 给该 img 节点设置 src,可以看到,在图片被加载好之前,页面中有一段长长的空白时间。
复制代码
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: