学习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 相关文章推荐
javascript 写类方式之六
Jul 05 Javascript
js加强的经典分页实例
Mar 15 Javascript
Jquery带搜索框的下拉菜单
May 06 Javascript
JavaScript的Module模式编程深入分析
Aug 13 Javascript
微信公众号开发 实现点击返回按钮就返回到聊天界面
Dec 15 Javascript
获取JavaScript异步函数的返回值
Dec 21 Javascript
jQuery实现打开网页自动弹出遮罩层或点击弹出遮罩层功能示例
Oct 19 jQuery
vue实现点击展开点击收起效果
Apr 27 Javascript
layui问题之模拟table表格中的选中按钮选中事件的方法
Sep 20 Javascript
微信小程序全局变量GLOBALDATA的定义和调用过程解析
Sep 23 Javascript
Vue实现简单的留言板
Oct 23 Javascript
Angular性能优化之第三方组件和懒加载技术
May 10 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
PHP的FTP学习(三)
2006/10/09 PHP
php函数的常用方法及注意之处小结
2011/07/10 PHP
php中运用http调用的GET和POST方法示例
2014/09/29 PHP
php批量删除超链接的实现方法
2015/10/19 PHP
Laravel框架在本地虚拟机快速安装的方法详解
2018/06/11 PHP
JavaScript关于select的相关操作说明
2010/01/13 Javascript
jquery中checkbox全选失效的解决方法
2014/12/26 Javascript
JavaScript实现鼠标滑过处生成气泡的方法
2015/05/16 Javascript
js实现继承的5种方式
2015/12/01 Javascript
浅析Bootstrap验证控件的使用
2016/06/23 Javascript
js判断浏览器是否支持严格模式的方法
2016/10/04 Javascript
react开发教程之React 组件之间的通信方式
2017/08/12 Javascript
vue-router懒加载速度缓慢问题及解决方法
2018/11/25 Javascript
Element-UI中Upload上传文件前端缓存处理示例
2019/02/21 Javascript
解决vue 子组件修改父组件传来的props值报错问题
2019/11/09 Javascript
js实现时钟定时器
2020/03/26 Javascript
Electron整合React使用搭建开发环境的步骤详解
2020/06/07 Javascript
微信小程序实现列表左右滑动
2020/11/19 Javascript
[03:18]DOTA2放量测试专访820:希望玩家加入国服大家庭
2013/08/25 DOTA
python合并文本文件示例
2014/02/07 Python
基于python调用psutil模块过程解析
2019/12/20 Python
基于python实现复制文件并重命名
2020/09/16 Python
用sleep间隔进行python反爬虫的实例讲解
2020/11/30 Python
基于Python的接口自动化unittest测试框架和ddt数据驱动详解
2021/01/27 Python
css3 border旋转时的动画应用
2016/01/22 HTML / CSS
阿迪达斯印尼官方网站:adidas印尼
2020/02/10 全球购物
KIKO MILANO俄罗斯官网:意大利领先的化妆品和护肤品品牌
2021/01/09 全球购物
世界上最大的铁人三项商店:Tri UK
2020/11/04 全球购物
小学开学寄语
2014/01/19 职场文书
如何写一封打动人心的求职信
2014/02/17 职场文书
公司感恩节活动策划书
2014/10/11 职场文书
整改报告怎么写
2014/11/06 职场文书
2014年社团工作总结范文
2014/11/27 职场文书
委托收款证明
2015/06/23 职场文书
Python使用random模块实现掷骰子游戏的示例代码
2021/04/29 Python
Python+OpenCV实现图片中的圆形检测
2022/04/07 Python