概念

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

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

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

实现

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

保护代理:

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

// 主体,发送消息
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

JS 设计模式六 -- 代理模式的更多相关文章

  1. js设计模式——1.代理模式

    js设计模式——1.代理模式 以下是代码示例 /*js设计模式——代理模式*/ class ReadImg { constructor(fileName) { this.fileName = file ...

  2. js设计模式之代理模式以及订阅发布模式

    为啥将两种模式放在一起呢?因为这样文章比较长啊. 写博客的目的我觉得首要目的是整理自己的知识点,进而优化个人所得知识体系.知识成为个人的知识,就在于能够用自己的话表达同一种意义. 本文是设计模式系列文 ...

  3. js设计模式总结-代理模式

    代理模式 解决哪一类问题 从字面意思上理解,代理模式解决对一个对象的直接访问,这种直接访问可能是"不方便"的,所谓"不方便"可能是直接访问成本比较大(在前端领域 ...

  4. 浅谈js设计模式之代理模式

    代理模式是一种非常有意义的模式,在生活中可以找到很多代理模式的场景.比如,明星都有经纪人作为代理.如果想请明星来办一场商业演出,只能联系他的经纪人.经纪人会把商业演出的细节和报酬都谈好之后,再把合同交 ...

  5. C#设计模式(13)——代理模式(Proxy Pattern)

    一.引言 在软件开发过程中,有些对象有时候会由于网络或其他的障碍,以至于不能够或者不能直接访问到这些对象,如果直接访问对象给系统带来不必要的复杂性,这时候可以在客户端和目标对象之间增加一层中间层,让代 ...

  6. JS设计模式——5.单体模式

    JS设计模式——5.单体模式 http://www.cnblogs.com/JChen666/p/3610585.html   单体模式的优势 用了这么久的单体模式,竟全然不知!用它具体有哪些好处呢? ...

  7. 乐在其中设计模式(C#) - 代理模式(Proxy Pattern)

    原文:乐在其中设计模式(C#) - 代理模式(Proxy Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 代理模式(Proxy Pattern) 作者:webabcd 介绍 为 ...

  8. Java设计模式之代理模式(静态代理和JDK、CGLib动态代理)以及应用场景

    我做了个例子 ,需要可以下载源码:代理模式 1.前言: Spring 的AOP 面向切面编程,是通过动态代理实现的, 由两部分组成:(a) 如果有接口的话 通过 JDK 接口级别的代理 (b) 如果没 ...

  9. 设计模式之代理模式之二(Proxy)

    from://http://www.cnblogs.com/xwdreamer/archive/2012/05/23/2515306.html 设计模式之代理模式之二(Proxy)   0.前言 在前 ...

随机推荐

  1. React教程(一) React介绍与搭建

    React的介绍: React来自于Facebook公司的开源项目 React 可以开发单页面应用 spa(单页面应用) react 组件化模块化 开发模式 React通过对DOM的模拟(虚拟dom) ...

  2. C# 《编写高质量代码改善建议》整理&笔记 --(三)泛型&委托&事件

    1.泛型 基于泛型,我们可以将类型参数化,以便更大范围地进行代码复用.同时,它减少了泛型类及泛型方法中的转型, 确保类型安全. 1)总是优先考虑泛型 优点:可重用性,类型安全,高效率. 2)避免在泛型 ...

  3. Abp中使用可视化的日志面板

    Abp中使用可视化的日志面板 如果你还不了解LogDashboard请看这里. ABP的相关知识不做介绍如果有需要请阅读ABP官方文档 ABP是Net下非常优秀的开发框架,在中国很多的项目都正在使用它 ...

  4. SmartSql 介绍

    介绍 SmartSql = MyBatis + Cache(Memory | Redis) + R/W Splitting +Dynamic Repository + Diagnostics .... ...

  5. Java设计模式系列-装饰器模式

    原创文章,转载请标注出处:<Java设计模式系列-装饰器模式> 一.概述 装饰器模式作用是针对目标方法进行增强,提供新的功能或者额外的功能. 不同于适配器模式和桥接模式,装饰器模式涉及的是 ...

  6. Sql学习笔记(二)—— 条件查询

    上篇简单介绍了一下sql的一些基础增删改查语句,而针对多种多样的查询语句则未详细说明,这一篇继续记录一下关于各种条件查询的知识. 1.按列名进行查询 语句: select stuName , stuA ...

  7. docker run 之后执行多条命令

    执行 ls docker run microsoft/dotnet ls && cd /root 执行 多条使用sh -c命令 在run后面加了一个sh -c命令,后面直接加多条语句即 ...

  8. C# 反射 判断类的延伸类型

    判断类型是否被继承.实现 1.判断是否实现了指定接口 添加测试类: public class TestClass2 : TestClass1 { } public class TestClass1 : ...

  9. day07 Class_field_method_反射

    Class 由于Class类没有公共构造方法,所有创建Class的对象的方法有以下几种:   1).通过Class.forName()静态方法返回Class类的一个实例 Class cls=Class ...

  10. Error fetching https://gems.ruby-china.org/: bad response Not Found 404 (https://gems.ruby-china.org/specs.4.8.gz) 报错解决办法

    执行换源操作 gem source -a https://gems.ruby-china.org/ 时报错: Error fetching https://gems.ruby-china.org/: ...