学习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 相关文章推荐
DOM下的节点属性和操作小结
May 14 Javascript
clientX,pageX,offsetX,x,layerX,screenX,offsetLeft区别分析
Mar 12 Javascript
JavaScript版TAB选项卡效果实例
Aug 16 Javascript
js字符串转成JSON
Nov 07 Javascript
jQuery中nextUntil()方法用法实例
Jan 07 Javascript
js获得当前系统日期时间的方法
May 06 Javascript
JavaScript实现带标题的图片轮播特效
May 20 Javascript
jQuery学习心得总结(必看篇)
Jun 10 Javascript
jquery+css实现下拉列表功能
Sep 03 jQuery
vue-cli实现多页面多路由的示例代码
Jan 30 Javascript
基于jquery实现左右上下移动效果
May 02 jQuery
js计算两个日期间的天数月的实例代码
Sep 20 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中替换换行符的几种方法小结
2012/10/15 PHP
兼容各大浏览器带关闭按钮的漂浮多组图片广告代码
2014/06/05 PHP
mod_php、FastCGI、PHP-FPM等PHP运行方式对比
2015/07/02 PHP
php的命名空间与自动加载实现方法
2019/08/25 PHP
javascript 复杂的嵌套环境中输出单引号和双引号
2009/05/26 Javascript
判断用户的在线状态 onbeforeunload事件
2011/03/05 Javascript
将HTMLCollection/NodeList/伪数组转换成数组的实现方法
2011/06/20 Javascript
深入理解javascript的执行顺序
2014/04/04 Javascript
js和jquery中循环的退出和继续学习记录
2014/09/06 Javascript
jQuery中index()方法用法实例
2014/12/27 Javascript
javascript自定义右键弹出菜单实现方法
2015/05/25 Javascript
基于jquery实现图片相关操作(重绘、获取尺寸、调整大小、缩放)
2015/12/25 Javascript
实例剖析AngularJS框架中数据的双向绑定运用
2016/03/04 Javascript
JS实现输入框提示文字点击时消失效果
2016/07/19 Javascript
浅谈JSON.stringify()和JOSN.parse()方法的不同
2016/08/29 Javascript
微信小程序开发探究
2016/12/27 Javascript
javascript数据结构之串的概念与用法分析
2017/04/12 Javascript
mpvue 单文件页面配置详解
2018/12/02 Javascript
详解vue项目中实现图片裁剪功能
2019/06/07 Javascript
Vue项目中使用jsonp抓取跨域数据的方法
2019/11/10 Javascript
js实现踩五彩块游戏
2020/02/08 Javascript
jQuery实现简单轮播图效果
2020/12/27 jQuery
[05:05]给小松五分钟系列 第二期介绍为什么打DOTA2
2014/07/02 DOTA
python 切片和range()用法说明
2013/03/24 Python
python递归计算N!的方法
2015/05/05 Python
python3将视频流保存为本地视频文件
2018/06/20 Python
Python实现使用request模块下载图片demo示例
2019/05/24 Python
python3.4 将16进制转成字符串的实例
2019/06/12 Python
python代理工具mitmproxy使用指南
2019/07/04 Python
Python爬取腾讯视频评论的思路详解
2019/12/19 Python
keras Lambda自定义层实现数据的切片方式,Lambda传参数
2020/06/11 Python
Python局部变量与全局变量区别原理解析
2020/07/14 Python
python 线程的五个状态
2020/09/22 Python
Python  Asyncio模块实现的生产消费者模型的方法
2021/03/01 Python
css3实现可拖动的魔方3d效果
2019/05/07 HTML / CSS
2015小学五年级班主任工作总结
2015/05/21 职场文书