概念

为一个对象提供一个代用品或占位符,以便控制对它的访问。

当客户不方便直接访问一个对象的时候,需要提供一个替身对象来控制对这个对象的访问。

替身对象对请求做出一些处理之后, 再把请求转交给本体对象。

实现

代理模式共有三种:保护代理、虚拟代理、缓存代理

保护代理:

用于控制不同权限的对象对目标权限的访问,实现访问访问主题的控制行为。

// 主体,发送消息
function sendMsg(msg) {
console.log(msg);
} // 代理,对消息进行过滤
function proxySendMsg(msg) {
// 无消息则直接返回
if (typeof msg === 'undefined') {
console.log('No Msg');
return;
} // 有消息则进行过滤
msg = "收到的msg是:" + msg; sendMsg(msg);
} sendMsg("msg1"); // msg1
proxySendMsg('msg2'); // 收到的msg是:msg2
proxySendMsg(); // No Msg

虚拟代理

虚拟代理 用于控制对创建开销很大的本体访问,它会把本体的实例化推迟到有方法被调用的时候,是最常用的一种代理。

使用虚拟代理来实现图片预加载

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("http://img.lanrentuku.com/img/allimg/1212/5-121204193Q9-50.gif");
img.src = src;
}
}
})();
// 调用方式
ProxyImage.setSrc("https://img.alicdn.com/tps/i4/TB1b_neLXXXXXcoXFXXc8PZ9XXX-130-200.png");

使用虚拟代理实现函数防抖

// 函数防抖,频繁操作中不处理,直到操作完成之后(再过 delay 的时间)才一次性处理,执行最后一次操作
function debounce(fn, delay) {
delay = delay || 200; var timer = null; return function() {
var arg = arguments; // 每次操作时,清除上次的定时器
clearTimeout(timer);
timer = null; // 定义新的定时器,一段时间后进行操作
timer = setTimeout(function() {
fn.apply(this, arg);
}, delay);
}
}; var count = 0; // 主体
function scrollHandle(e) {
console.log(e.type, ++count); // scroll
} // 代理
var proxyScrollHandle = (function() {
return debounce(scrollHandle, 500);
})(); window.onscroll = proxyScrollHandle;

缓存代理

缓存代理 可以为一些开销大的运算结果提供暂时的缓存,在下一次运算时,如果传递进来的参数跟之前一致,则可以直接返回前面存储的运算结果。

使用缓存代理计算乘法、加法

// 计算乘法
var mult = function(){
var a = 1;
for(var i = 0,ilen = arguments.length; i < ilen; i+=1) {
a = a*arguments[i];
}
return a;
};
// 计算加法
var plus = function(){
var a = 0;
for(var i = 0,ilen = arguments.length; i < ilen; i+=1) {
a += arguments[i];
}
return a;
}
// 代理函数
var proxyFunc = 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 = proxyFunc(mult);
console.log(proxyMult(1,2,3,4)); //
console.log(proxyMult(1,2,3,4)); // 缓存取 24 var proxyPlus = proxyFunc(plus);
console.log(proxyPlus(1,2,3,4)); //
console.log(proxyPlus(1,2,3,4)); // 缓存取 10

最新文章

  1. spring+mybatis 手动开启和提交事务
  2. ejs-mate
  3. jQuery实现两个按钮的位置互换
  4. c++学习_2
  5. PHP程序开发人员要掌握的知识
  6. 看大数据时代下的IT架构(1)业界消息队列对比
  7. Razor button
  8. angular中的$http配置和参数
  9. CSS3新特性汇总
  10. 利用Hive分析nginx日志
  11. webservice学习教程(三)--
  12. android 获取手机GSM/CDMA信号信息,并获得基站信息
  13. LeetCode(55): 跳跃游戏
  14. Dom捕捉事件和冒泡事件-原理与demo测试
  15. 定位amdu无法使用的根因并解决
  16. pta l2-28(秀恩爱分得快)
  17. 浅入浅出Lambda表达式
  18. as3 代码优化
  19. 对this的理解?
  20. PHP递归方式把一个数组里面的null转换为空字符串”的方法

热门文章

  1. React 与 React-Native 使用同一个 meteor 后台
  2. Java笔试题库之选题题篇【141-210题】
  3. 从壹开始微服务 [ DDD ] 之八 ║剪不断理还乱的 值对象和Dto
  4. 使用 .NET Core 开发 BT Tracker 服务器
  5. redis的list类型!!!!
  6. qml demo分析(threadedanimation-线程动画)
  7. 【Android Studio安装部署系列】三十一、从Android studio3.0.0升级到Android studio3.0.1
  8. ProgressWheelDialogUtil【ProgressWheel Material样式进度条对话框】
  9. Powershell:关于PSCustomObject你想知道的一切(译)
  10. [Vue] vuex进行组件间通讯