微信打分小程序_JavaScript设计模式之代理模式详解

2021-01-12 10:40 admin
JavaScript设计模式之代理模式详解       这篇文章主要为大家详细介绍了JavaScript设计模式之代理模式,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

代理模式是非常常见的模式,比如我们使用的VPN工具,明星的经纪人,都是代理模式的例子。但是,有人会疑问,明明可以直接访问对象,为什么中间还要加一个壳呢?这也就说到了代理模式的好处。在我看来,代理模式最大的好处,就是在不动原有对象的同时,可以给原有对象增加一些新的特性或者行为。

 * pre:代理模式
 * 小明追求A,B是A的好朋友,小明比较腼腆,不好意思直接将花交给A,
 * 于是小明将花交给B,再由B交给A.
//----------- 示例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 --------------
// 使用代理1
var Flower = function() {};
var xiaoming = {
 sendFlower: function(target) {
 var flower = new Flower();
 B.receiveFlower(flower);
var B = {
 receiveFlower: function(flower) {
 A.receiveFlower(flower);
var A = {
 receiveFlower: function(flower) {
 console.log("收到花:" + flower);
xiaoming.sendFlower(B);
//------------- 示例3 ---------------
 * 使用代理2
 * 从示例1和示例2,看不出使用代理有什么用处,B只不过是从中间转手了一次。
 * 接下来,我们想一下。给喜欢的人送花,怎样才能提高成功率呢?
 * 我们都知道,人有心情好和心情差的时候,当美女心情好的时候,送花成功的概率自然要大些。
 * 于是,我们将代理升级,监听美女的心情,心情好的时候再给她送花。
 * 为了演示,我们假设2秒后,A的心情变好。
var Flower = function() {};
var xiaoming = {
 sendFlower: function(target) {
 var flower = new Flower();
 B.receiveFlower(flower);
var B = {
 receiveFlower: function(flower) {
 A.listenGoodMood(function() {
 A.receiveFlower(flower);
var A = {
 receiveFlower: function(flower) {
 console.log("收到花:" + flower);
 listenGoodMood: function(fn) {
 setTimeout(function() {
 fn.apply(this, arguments);
 }, 2000);
xiaoming.sendFlower(B);
// ---------- 示例4 ---------------
 * 【代理模式用处】:虚拟代理
 * 这里以加载图片为例,我们都知道当网络不畅以及图片过大时,图片加载都比较慢,
 * 为了更好的用户体验,我们都会在原图片未加载完成前,加上loading图片。
 * */
//--4 _01未使用代理--
var myImage = (function() {
 var imgNode = document.createElement("img");
 document.body.appendChild(imgNode);
 return {
 setSrc: function(src) {
 this.imgNode.src = src;
})();
myImage.setSrc("xxx");
//--4_02使用代理--
var proxyMyImage = (function() {
 var img = new Image();
 img.onload = function() {
 myImage.setSrc(this.src);
 return {
 setSrc: function(src) {
 myImage.setSrc("loading.jpg");
 img.src = src;
})();
proxyMyImage.setSrc("xxx");
 * [注]:这里可以看到代理模式的好处:在不改变原有接口的同时,可以为系统添加新的行为。
//--------- 示例5---------------
 * 【代理模式用处】:合并http请求
 * 这里以选择文件同步为例。
 * 以往用户同步文件,在用户选中的时候就触发,这种方法做到了实时性,但无疑增加了网络的开销。
 * 实际在使用的过程中,往往并不需要立刻就同步。
 * 以下通过代理模式,将在用户选中文件2秒后进行同步请求。
 * */
// --- 包含一段html代码,请自行添加到一个文件中 ------
 html 
 body 
 button id="input" 点我上传 /button 
 input type="checkbox" id="1" /input 1
 input type="checkbox" id="2" /input 2
 input type="checkbox" id="3" /input 3
 input type="checkbox" id="4" /input 4
 input type="checkbox" id="5" /input 5
 input type="checkbox" id="6" /input 6
 input type="checkbox" id="7" /input 7
 input type="checkbox" id="8" /input 8
 input type="checkbox" id="9" /input 9
 /body 
 /html 
// -- 上传文件 --
var synchronizeFile = function(id) {
 console.log("开始同步文件:" + id);
var proxySynchronizeFiles = (function() {
 var fileCache = [],
 timer;
 return function(id) {
 fileCache.push(id);
 if(timer) {
 return;
 timer = setTimeout(function() {
 synchronizeFile(fileCache.join(","));
 clearTimeout(timer);
 timer = null;
 checkArr.length = 0;
 }, 2000);
})();
var checkArr = document.getElementsByTagName("input");
for(var i = 0, c; c = checkArr[i++];) {
 c.onclick = function() {
 if(this.checked == true) {
 proxySynchronizeFiles(this.id);
// ------------ 示例6 -----------------
 * 【代理模式用处】:缓存代理
 * 以计算器为例,比如计算某些数的乘积,当参数重复时,我们希望不用重复计算,直接返回结果。
 * 以下用到代理模式做缓存。
var mult = function() {
 if(!arguments) {
 console.log("请输入参数");
 return;
 var a = 1;
 for(var i = 0, b; b = arguments[i++];) {
 a = a * b;
 return a;
var proxyMult = (function() {
 var cache = {};
 return function() {
 var str = Array.prototype.join.call(arguments, ",");
 if(str in cache) {
 console.log("重复return.");
 return cache[str];
 return cache[str] = mult.apply(this, arguments);
})();
console.log(proxyMult(2, 3, 4));
console.log(proxyMult(2, 3, 4));
//------------ 示例7 --------------
 * 缓存代理升级 - 通用版计算
var mult = function() {
 if(!arguments) {
 return;
 var t = 1;
 for(var i = 0, a; a = arguments[i++];) {
 t = t * a;
 return t;
var plus = function() {
 if(!arguments) {
 return;
 var t = 0;
 for(var a of arguments) {
 t += a;
 return t;
var createProxyCaculate = function(fn) {
 var cache = {};
 return function() {
 var str = Array.prototype.join.call(arguments, ",");
 if(str in cache) {
 console.log("重复return" + str);
 return cache[str];
 return cache[str] = fn.apply(this, arguments);
var proxyMult = createProxyCaculate(mult);
var proxyPlus = createProxyCaculate(plus);
console.log(proxyMult(2, 3, 4));
console.log(proxyMult(2, 3, 4));

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持凡科。