学习JavaScript设计模式(代理模式)


Posted in Javascript onDecember 03, 2015

代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问
代理模式的用处(个人理解):为了保障当前对象的单一职责(相对独立性),而需要创建另一个对象来处理调用当前对象之前的一些逻辑以提高代码的效率、状态判断等。
代理模式中最常用的是虚拟代理缓存代理

一、虚拟代理
虚拟代理是把一些开销很大的对象,延迟到真正需要它的时候才去创建执行
示例: 虚拟代理实现图片预加载

// 图片加载函数
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:/loading.png");
      img.src = src;
    }
  }
})();

// 调用代理对象加载图片
proxyImage.setSrc( "http://images/qq.jpg");

示例: 虚拟代理合并HTTP请求
假设一个功能需要频繁的进行网络请求,这会造成相当大的开销,解决方案是通过一个代理函数来收集一段时间之内的请求,一次性发给服务器。
例如:做一个文件同步的功能,当我们选中一个文件时,就同步到另外一台备用服务器上

// 文件同步函数
var synchronousFile = function( id ){
  console.log( "开始同步文件,id为:" + id );
}
// 使用代理合并请求
var proxySynchronousFile = (function(){
  var cache = [], // 保存一段时间内需要同步的ID
    timer; // 定时器指针

  return function( id ){
    cache[cache.length] = id;
    if( timer ){
      return;
    }

    timer = setTimeout( function(){
      proxySynchronousFile( cache.join( "," ) ); // 2s 后向本体发送需要同步的ID集合
      clearTimeout( timer ); // 清空定时器
      timer = null;
      cache = []; // 晴空定时器
    },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 += arguments[i];
  }
  return a;
};
// 创建缓存代理的工厂
var createProxyFactory = function( fn ){
  var cache = {}; // 缓存 - 存放参数和计算后的值
  return function(){
    var args = Array.prototype.join.call(arguments, "-");
    if( args in cache ){ // 判断出入的参数是否被计算过
      console.log( "使用缓存代理" );
      return cache[args];
    }
    return cache[args] = fn.apply( this, arguments );
  }
};
// 创建代理
var proxyMult = createProxyFactory( mult ),
  proxyPlus = createProxyFactory( plus );

console.log( proxyMult( 1, 2, 3, 4 ) ); // 输出: 24
console.log( proxyMult( 1, 2, 3, 4 ) ); // 输出: 缓存代理 24
console.log( proxyPlus( 1, 2, 3, 4 ) ); // 输出: 10
console.log( proxyPlus( 1, 2, 3, 4 ) ); // 输出: 缓存代理 10

以上三个示例为大家详细介绍了javascript代理模式,希望对大家的学习有所帮助。

Javascript 相关文章推荐
用JS操作FRAME中的IFRAME及其内容的实现代码
Jul 26 Javascript
深入理解JavaScript系列(15) 函数(Functions)
Apr 12 Javascript
js获取url参数值的两种方式
Sep 10 Javascript
jquery中focus()函数实现当对象获得焦点后自动把光标移到内容最后
Sep 29 Javascript
原生JS可拖动弹窗效果实例代码
Nov 09 Javascript
javascript如何动态加载表格与动态添加表格行
Nov 27 Javascript
javascript动态修改Li节点值的方法
Jan 20 Javascript
jQuery三级下拉列表导航菜单代码分享
Apr 15 Javascript
js纯数字逐一停止显示效果的实现代码
Mar 16 Javascript
详解RequireJs官方使用教程
Oct 31 Javascript
vue中使用v-for时为什么不能用index作为key
Apr 04 Javascript
js 压缩图片的示例(只缩小体积,不更改图片尺寸)
Oct 21 Javascript
全面解析Bootstrap图片轮播效果
Dec 03 #Javascript
谈谈基于iframe、FormData、FileReader三种无刷新上传文件的方法
Dec 03 #Javascript
解决JavaScript数字精度丢失问题的方法
Dec 03 #Javascript
Javascript实现检测客户端类型代码封包
Dec 03 #Javascript
javascript学习小结之prototype
Dec 03 #Javascript
简单实现JS对dom操作封装
Dec 02 #Javascript
jQuery实现获取绑定自定义事件元素的方法
Dec 02 #Javascript
You might like
zend framework框架中url大小写问题解决方法
2014/08/19 PHP
VPS中使用LNMP安装WordPress教程
2014/12/28 PHP
php判断邮箱地址是否存在的方法
2016/02/13 PHP
js随机颜色代码的多种实现方式
2013/04/23 Javascript
JavaScript将页面表格导出为Excel的具体实现
2013/12/27 Javascript
js动画效果制件让图片组成动画代码分享
2014/01/14 Javascript
Nodejs学习item【入门手上】
2016/05/05 NodeJs
Angularjs处理页面闪烁的解决方法
2017/03/09 Javascript
JavaScript数据结构之单链表和循环链表
2017/11/28 Javascript
详解extract-text-webpack-plugin 的使用及安装
2018/06/12 Javascript
Vue自定义toast组件的实例代码
2018/08/15 Javascript
NodeJs实现简易WEB上传下载服务器
2019/08/10 NodeJs
Angular5整合富文本编辑器TinyMCE的方法(汉化+上传)
2020/05/26 Javascript
基于 Vue 的 Electron 项目搭建过程图文详解
2020/07/22 Javascript
微信小程序实现登录注册功能
2020/12/29 Javascript
[01:15:56]2018DOTA2亚洲邀请赛3月30日 小组赛A组 TNC VS Newbee
2018/03/31 DOTA
Python脚本简单实现打开默认浏览器登录人人和打开QQ的方法
2016/04/12 Python
Python使用numpy产生正态分布随机数的向量或矩阵操作示例
2018/08/22 Python
Flask框架学习笔记之消息提示与异常处理操作详解
2019/08/15 Python
python request 模块详细介绍
2020/11/10 Python
基于python+selenium自动健康打卡的实现代码
2021/01/13 Python
html5服务器推送_动力节点Java学院整理
2017/07/12 HTML / CSS
HEMA英国:荷兰原创设计
2018/08/28 全球购物
Watchshop德国:欧洲在线手表No.1
2019/06/20 全球购物
英国婴儿产品专家:Samuel Johnston
2020/04/20 全球购物
请解释流与文件有什么不同
2016/07/29 面试题
教育实习生的自我评价分享
2013/11/21 职场文书
医学专业毕业生个人的求职信
2013/12/04 职场文书
网络工程专业自荐信范文
2014/03/16 职场文书
小学三年级学生评语
2014/04/22 职场文书
2015中秋节慰问信范文
2015/03/23 职场文书
无工作证明怎么写
2015/06/15 职场文书
驾驶员管理制度范本
2015/08/06 职场文书
护士心得体会范文
2016/01/25 职场文书
Nginx域名转发https访问的实现
2021/03/31 Servers
Vue Element UI自定义描述列表组件
2021/05/18 Vue.js