学习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 相关文章推荐
表单(FORM)的一些实用效果代码
Mar 25 Javascript
js post方式传递提交的实现代码
May 31 Javascript
jquery五角星评分插件示例分享
Feb 21 Javascript
推荐一个自己用的封装好的javascript插件
Jan 29 Javascript
jquery遍历函数siblings()用法实例
Dec 24 Javascript
JS控制弹出悬浮窗口(一览画面)的实例代码
May 30 Javascript
ES6中Math对象新增的方法实例详解
Apr 25 Javascript
Swiper自定义分页器使用详解
Dec 28 Javascript
jQuery替换节点元素的操作方法
Mar 18 jQuery
Vue动态组件和异步组件原理详解
May 06 Javascript
微信小程序引入Vant组件库过程解析
Aug 06 Javascript
vue改变循环遍历后的数据实例
Nov 07 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面向对象分析设计的61条军规小结
2010/07/17 PHP
解决php使用异步调用获取数据时出现(错误c00ce56e导致此项操作无法完成)
2013/07/03 PHP
php实现网站文件批量压缩下载功能
2015/10/28 PHP
使用jQuery模板来展现json数据的代码
2010/10/22 Javascript
扩展easyui.datagrid,添加数据loading遮罩效果代码
2010/11/02 Javascript
JS 控制小数位数的实现代码
2011/08/02 Javascript
jquery滚动组件(vticker.js)实现页面动态数据的滚动效果
2013/07/03 Javascript
node.js中使用socket.io制作命名空间
2014/12/15 Javascript
js下拉选择框与输入框联动实现添加选中值到输入框的方法
2015/08/17 Javascript
jQuery实现默认是闭合的FAQ展开效果菜单
2015/09/14 Javascript
JavaScript学习笔记整理_用于模式匹配的String方法
2016/09/19 Javascript
微信小程序 解决请求服务器手机预览请求不到数据的方法
2017/01/04 Javascript
vue定义全局变量和全局方法的方法示例
2018/08/01 Javascript
关于javascript中的promise的用法和注意事项(推荐)
2021/01/15 Javascript
[04:16]DOTA2英雄梦之声_第09期_斧王
2014/06/21 DOTA
[01:31:02]TNC vs VG 2019国际邀请赛淘汰赛 胜者组赛BO3 第一场
2019/08/22 DOTA
python嵌套函数使用外部函数变量的方法(Python2和Python3)
2016/01/31 Python
Python 中 Virtualenv 和 pip 的简单用法详解
2017/08/18 Python
Python如何快速上手? 快速掌握一门新语言的方法
2017/11/14 Python
Python实现爬取百度贴吧帖子所有楼层图片的爬虫示例
2018/04/26 Python
python版本的仿windows计划任务工具
2018/04/30 Python
python粘包问题及socket套接字编程详解
2019/06/29 Python
Python sys模块常用方法解析
2020/02/20 Python
中学生校园广播稿
2014/01/16 职场文书
演讲比赛获奖感言
2014/02/02 职场文书
玲玲的画教学反思
2014/02/04 职场文书
电子商务专业毕业生求职信
2014/06/12 职场文书
商场租赁意向书
2014/07/30 职场文书
国庆节标语大全
2014/10/08 职场文书
2014大学班主任工作总结
2014/11/08 职场文书
实习介绍信模板
2015/01/30 职场文书
蓬莱阁导游词
2015/02/04 职场文书
MySQL索引失效的典型案例
2021/06/05 MySQL
基于Pygame实现简单的贪吃蛇游戏
2021/12/06 Python
详解Python+OpenCV绘制灰度直方图
2022/03/22 Python
Windows7下FTP搭建图文教程
2022/08/05 Servers