博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
04代理,迭代器
阅读量:4321 次
发布时间:2019-06-06

本文共 7098 字,大约阅读时间需要 23 分钟。

代理模式

  • 为一个对象提供一个代用品或占位符。以便控制对他的访问;
面向对象设计原则-单一职责原则
  • 就一个类(对象,函数)而言,应该仅有一个引起他变化的原因;(低耦合)

代理和本体借口的一致性

  • 当不需要代理的时候可以替换回本体

保护代理

  • 过滤请求;可以用于控制不同权限对象对目标对象的访问

虚拟代理

  • 把一些开销很大的对象,延迟到真正需要的时候才创建;
  • 实现图片预加载
var myImage = (function() {  var imgNode = document.createElement('img');  document.body.appendChild(imgNode);  return function(src) {    imgNode.src = src;  };})();var proxyImage = (function() {  var img = new Image;  img.onload = function() {    myImage(this.src);  };  return function(src) {    myImage('picture/loading.jpg');    img.src = src;  }})();proxyImage('http://tp3.sinaimg.cn/1805666510/180/5718258464/1');
  • 实现合并请求
var synchronousFile = function (id) {  console.log('开始同步 ' + id);};var proxySynchronousFile = (function() {  var cache = [], timer;  return function(id) {    cache.push(id);    if(timer)      return;    timer = setTimeout(function() {      synchronousFile(cache.join(','));      clearTimeout(timer);      timer = null;      cache.length = 0;    }, 2000);  //2秒延迟后一次性处理  };})();var checkbox = document.getElementsByTagName('input');for(var i = 0, c; c = checkbox[i++];) {  c.onclick = function() {    if(this.checked === true)      proxySynchronousFile(this.id);  }};

在堕性加载中的应用

var miniConsole = (function(){  var cache = [];  var handler = function( ev ){    if ( ev.keyCode === 13 ){ //enter      var script = document.createElement( 'script' );      script.onload = function(){        for ( var i = 0, fn; fn = cache[ i++ ]; ){          fn();        }      };      script.src = 'log.js';      document.getElementsByTagName( 'head' )[0].appendChild(script);      document.body.removeEventListener( 'keydown', handler );    }  };  document.body.addEventListener( 'keydown', handler, false );  return {    log: function(){      var args = arguments;      cache.push( function(){        return miniConsole.log.apply( miniConsole, args );  //缓存,当真正加载log.js再执行;      });    }  }})();miniConsole.log(0);miniConsole.log(1);//按下enter// log.js 代码miniConsole = {  log: function(){  // 真正代码略    console.log( Array.prototype.join.call( arguments ) );  }};

缓存代理

  • 为一些开销大的运算结果提供暂时的存储
var mult = function () {  var a = 1;  for(var i = 0, len = arguments.length; i < len; i++)    a = a * arguments[i];  return a;};var proxyMult = (function() {  var cache = {};  return function() {    var args = [].join.call(arguments, ',');    if(args in cache)      return cache[args]    return cache[args] = mult.apply(this, arguments);  };})();proxyMult(3,6,8);
  • 用于ajax异步请求: 如分页实现时讲数据缓存,下次请求同一页再输出;

利用高阶函数动态创建代理

  • 如将上面的proxyMult修改,使以后类似计算的缓存代理都用同一个函数产生
var createProxyFactory = function(fn) {  var cache = {};  return function() {    var args = [].join.call(arguments, ',');    if(args in cache)      return cache[args];    return cache[args] = fn.apply(this, arguments);  }};var proxyMult = createProxyFactory(mult);

其他代理

  • 防火墙代理:控制网络资源的访问;
  • 远程代理:为一个对象在不同的地址空间提供局部代表;
  • 保护代理:用于对象应该有不同访问权限的情况;
  • 智能引用代理:取代简单的指针,在访问对象时执行一些附加操作;
  • 写时即复制代理:通常用于复制一个庞大对象的情况;他延迟了复制的过程,当对象真正被修改时才进行复制;

  • 在编写业务代码的时候往往不需要预先设置使用代理模式,当真正发现不方便直接访问某个对象的时候再使用;

迭代器模式

  • 顺序访问一个聚合对象中各个元素,而又不需要暴露该对象的内部表示的方法;
  • 现在流行的大部分语言都有内置的迭代器实现;JS中如Array.prototype.forEach

内部迭代器

  • 内部已经定义好了迭代规则
var each = function (arr, callback) {  for(var i = 0, len = arr.length; i < len; i++)    callback.call(arr, i, arr[i]); //这里可以修改对象};each([1,2,3], function(index, value) {  console.log(this,index,value);});

外部迭代器

  • 必须显示地请求迭代下一个元素;增加了复杂度,但也增强累迭代器的灵活性;可以手工控制迭代过程;
var Iterator = function(obj) {  var current = 0, len = obj.length;  var next = function() {    current++;  }  var isDone = function() {    return current >= len; //如果length会自动修改那直接使用  }  var getCurrentIten = function() {    return obj[current];  }  return {    next: next,    isDone: isDone,    getCurrentIten: getCurrentIten  }};//一个比较数组相等的例子var compare = function(iterator1, iterator2) {  while(!iterator1.isDone() || !iterator2.isDone()) {    if(iterator1.getCurrentIten() !== iterator2.getCurrentIten())      throw new Error('不相等');    iterator1.next();    iterator2.next();  }  console.log('相等');};compare(Iterator([0,1,2]), Iterator([0,1,2]));

另一个迭代器实现

var Iterator = function (items, container) {  var container = container && document.getElementById(container) || document.body,      items = container.getElementsByTagName(items),      len = items.length,      index = 0,      splice = [].splice;  return {    first: function () {      index = 0;      return items[index];    },    second: function () {      index = len - 1;      return items[index];    },    pre: function () {      if(--index > 0)        return items[index];      else {        index = 0;        return null;      }    },    next: function () {      if(++index < len)         return items[index]      else {        index = len - 1;        return null;      }    },    get: function (num) {      index = num >= 0 ? num % len : num % len + len;      return items[index];    },    dealEach: function (fn) {      var args = splice.call(arguments, 1);      for(var i = 0; i < len; i++) {        fn.apply(items[i], args);      }    },    dealItem: function (num, fn) {      fn.apply(this.get(num), splice.call(arguments, 2))    },    exclusive: function (num, allFn, numFn) {      this.dealEach(allFn);      if(Object.prototype.toString.call(num) === '[object Array]') {        for(var i = 0, l = num.length; i < l; i++) {          this.dealItem(num[i], numFn);        }       } else {        this.dealItem(num, numFn);      }    }  }};var demo = new Iterator('li', 'container');console.log(demo.first());console.log(demo.pre());console.log(demo.next());console.log(demo.get(3));demo.dealEach(function(text, color) {  this.innerHTML = text;  this.style.background = color;}, 'test', 'pink');demo.exclusive([2,3], function () {  this.innerHTML = '被排除的';  this.style.background = 'green';}, function () {  this.innerHTML = '被选中的';  this.style.background = 'red';})

迭代类数组和字面量对象

  • 实际上只要聚合对象拥有length属性并可以下标访问就可以被迭代

应用例子

  • 比如一个功能里使用try-catch,if-else等根据实际情况尝试不同的执行函数;
  • 可以将所有要尝试的函数单独分开并设置尝试执行失败返回false;
  • 将所有要尝试的函数通过高迭代器执行,以后增加新的执行函数,只要按照一定顺序迭代就可以;
var iterator = function() {  for(var i = 0, fn; fn = arguments[i++];) {    var result = fn();    if(result !== false)      return result;  }};iterator(fn1, fn2, fn3, fn4);

同步变量迭代器

//同步变量var A = {  common: {},  client: {    user: {      username: '',      uid: ''    }  },  server: {}};//同步变量迭代取值器var AGetter = function (key) {  if(!A) return;  var result = A;  key = key.split('.');  for(var i = 0, l = key.length; i < l; i++) {    if(result[key[i]] !== undefined) {      result = result[key[i]];    } else {      return;    }  }  return result;};//同步变量迭代赋值器var ASetter = function (key, val) {  if(!A) return;  var result = A;  key = key.split('.');  for(var i = 0, l = key.length; i < l; i++) {    if (result[key[i]] === undefined) {      result[key[i]] = {};    }    if (!(result[key[i]] instanceof Object)) {      throw new Error('A. ' + key.splice(0, i + 1).join('.') + ' is not Object');      return false;    }    result = result[key[i]];  }  return result[key[i]] = val;};console.log(AGetter('client.user.username'));console.log(ASetter('client.server.new', 'on'));

转载于:https://www.cnblogs.com/jinkspeng/p/4582448.html

你可能感兴趣的文章
苹果 OS X制作u盘启动盘
查看>>
Jquery便利对象
查看>>
MVC: Connection String
查看>>
idea常用设置汇总
查看>>
Node.SelectNodes
查看>>
Lambda表达式语法进一步巩固
查看>>
Vue基础安装(精华)
查看>>
Git 提交修改内容和查看被修改的内容
查看>>
PAT - 1008. 数组元素循环右移问题 (20)
查看>>
请求出现 Nginx 413 Request Entity Too Large错误的解决方法
查看>>
配置php_memcache访问网站的步骤
查看>>
hibernate的id生成策略
查看>>
树莓派3B+学习笔记:5、安装vim
查看>>
[Spfa][bfs] Jzoj P5781 秘密通道
查看>>
企业帐号进行IPA的打包、分发、下载安装的详细流程(转载)
查看>>
《项目架构那点儿事》——快速构建Junit用例
查看>>
{"errmsg":"invalid weapp pagepath hint: [IunP8a07243949]","errcode":40165}微信的坑
查看>>
DB2V9.5数据库使用pdf
查看>>
Java Bigdecimal使用
查看>>
SQL注入之绕过WAF和Filter
查看>>