学习JavaScript设计模式之迭代器模式


Posted in Javascript onJanuary 19, 2016
  • 迭代器模式是指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。

JavaScript中的Array.prototype.forEach

一、jQuery中的迭代器

$.each([1, 2, 3], function(i, n) {
  console.log("当前下标为:"+ i + " 当前元素为:"+ n );
});

二、实现自己的迭代器

var each = function(ary, callback) {
  for(var i = 0, l = ary.length; i < l; i++) {
    callback.call(ary[i], i, ary[i]);
  }  
};
each([1, 2, 3], function(i, n) {
  console.log("当前下标为:"+ i + " 当前元素为:"+ n );
});

注意:区别于Array.prototype.forEach的参数!!!

[1, 2, 3].forEach(function(n, i, curAry){
  console.log("当前下标为:"+ i + " 当前元素为:"+ n + " 当前数组为:" + curAry);
})

三、内部迭代器、外部迭代器

(1)内部迭代器:已经定义好了迭代规则,它完全接手整个迭代过程,外部只需一次初始调用。上述自定义each即为内部迭代器!
(2)外部迭代器:必须显示地请求迭代下一个元素。
示例:判断两个数组是否相等

示例一:内部迭代器

// 内部迭代器
var each = function(ary, callback) {
  for(var i = 0, l = ary.length; i < l; i++) {
    callback.call(ary[i], i, ary[i]);
  }  
};
// 比较函数
var compareAry = function(ary1, ary2) {
  if(ary1.length != ary2.length) {
    throw new Error("不相等"); // return console.log("不相等"); 
  }
  // 且住
  each(ary1, function(i, n) {
    if(n !== ary2[i]) {
      // return console.log("不相等"); 
      // return 只能返回到each方法外,后续console.log("相等")会继续执行,所以这里得使用throw
      throw new Error("不相等");
    }
  });
  console.log("相等");
}

compareAry([1, 2, 3], [1, 2, 4]);

示例二:外部迭代器

// 外部迭代器
var Iterator = function(obj) {
  var current = 0,
    next = function() {
      current++;
    },
    isDone = function() {
      return current >= obj.length;  
    },
    getCurrentItem = function() {
      return obj[current];
    };
  return {
    next: next,
    isDone: isDone,
    getCurrentItem: getCurrentItem
  };
};
// 比较函数
var compareAry = function(iterator1, iterator2) {
  while( !iterator1.isDone() && !iterator2.isDone() ){
    if(iterator1.getCurrentItem() !== iterator2.getCurrentItem()) {
      throw new Error("不相等");
    }
    iterator1.next();
    iterator2.next();
  }
  console.log("相等");
}

compareAry(new Iterator([1, 2, 3]), new Iterator([1, 2, 4]));

四、终止迭代器

var each = function(ary, callback) {
  for(var i = 0, l = ary.length; i < l; i++) {
    if(callback.call(ary[i], i, ary[i]) === false) {
      break;
    }
  }
}

each([1, 2, 4, 1], function(i, n) {
  if(n > 3) {
    return false;
  }
  console.log(n);
});

五、应用(落地)

文件上传,根据不同的浏览器获取相应的上传组件对象。
对比《JavaScript设计模式?责任链模式》

var iteratorUploadObj = function() {
  for(var i = 0, fn; fn = arguments[i]; i++) {
    var uploadObj = fn();
    if(uploadObj !== false) {
      return uploadObj;
    }
  }
};

var uploadObj = iteratorUploadObj(getActiveUploadObj, getFlashUploadObj, getFormUploadObj);

function getActiveUploadObj() {
  try{
    return new ActiveObject("TXFTNActiveX.FTNUpload"); // IE上传控件
  }catch(e) {
    return false;
  }
}

function getFlashUploadObj() {
  if(supportFlash().f === 1) {
    var str = '<object type="application/x-shockwave-flash"></object>';
    return $(str).appendTo($("body"));
  }
  return false;
}

function getFormUploadObj() {
  var str = '<input name="file" type="file" class="ui-file" />';
  return $(str).appendTo($("body"));
}

// 是否支持flash
function supportFlash() {
  var hasFlash = 0; //是否安装了flash
  var flashVersion = 0; //flash版本
  if (document.all) {
    var swf = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');
    if (swf) {
      hasFlash = 1;
      VSwf = swf.GetVariable("$version");
      flashVersion = parseInt(VSwf.split(" ")[1].split(",")[0]);
    }
  } else {
    if (navigator.plugins && navigator.plugins.length > 0) {
    var swf = navigator.plugins["Shockwave Flash"];
      if (swf) {
        hasFlash = 1;
        var words = swf.description.split(" ");
        for (var i = 0; i < words.length; ++i) {
          if (isNaN(parseInt(words[i]))) continue;
          flashVersion = parseInt(words[i]);
        }
      }
    }
  }
  return { f: hasFlash, v: flashVersion };
}

希望本文所述对大家学习javascript程序设计有所帮助。

Javascript 相关文章推荐
JavaScript 命名空间 使用介绍
Aug 29 Javascript
jquery ui resize 中border-box的bug修正
Apr 26 Javascript
javascript中mouseover、mouseout使用详解
Jul 19 Javascript
JavaScript随机打乱数组顺序之随机洗牌算法
Aug 02 Javascript
微信小程序 PHP后端form表单提交实例详解
Jan 12 Javascript
javascript表单正则应用
Feb 04 Javascript
解决vue中修改export default中脚本报一大堆错的问题
Aug 27 Javascript
深入理解 TypeScript Reflect Metadata
Dec 12 Javascript
JavaScript随机数的组合问题案例分析
May 16 Javascript
小程序瀑布流组件实现翻页与图片懒加载
May 19 Javascript
Vue环境搭建+VSCode+Win10的详细教程
Aug 19 Javascript
浅析JavaScript中的事件委托机制跟深浅拷贝
Jan 20 Javascript
学习JavaScript设计模式之观察者模式
Apr 22 #Javascript
JS获取CSS样式(style/getComputedStyle/currentStyle)
Jan 19 #Javascript
详解javascript实现自定义事件
Jan 19 #Javascript
JS拖拽组件学习使用
Jan 19 #Javascript
理解JS绑定事件
Jan 19 #Javascript
AngularJS模块学习之Anchor Scroll
Jan 19 #Javascript
jQuery unbind()方法实例详解
Jan 19 #Javascript
You might like
开发大型PHP项目的方法
2006/10/09 PHP
用cookies来跟踪识别用户
2006/10/09 PHP
php curl基本操作详解
2013/07/23 PHP
php网站地图生成类示例
2014/01/13 PHP
php关联数组快速排序的方法
2015/04/17 PHP
Smarty变量用法详解
2016/05/11 PHP
PHP登录验证码的实现与使用方法
2016/07/07 PHP
解析arp病毒背后利用的Javascript技术附解密方法
2007/08/06 Javascript
js本身的局限性 别让javascript做太多事
2010/03/23 Javascript
jQuery替换textarea中换行的方法
2015/06/10 Javascript
JavaScript中数据结构与算法(四):串(BF)
2015/06/19 Javascript
JS模拟简易滚动条效果代码(附demo源码)
2016/04/05 Javascript
微信开发 消息推送实现代码
2016/10/21 Javascript
基于SpringMVC+Bootstrap+DataTables实现表格服务端分页、模糊查询
2016/10/30 Javascript
Vue.js仿Metronic高级表格(二)数据渲染
2017/04/19 Javascript
bootstrap 日期控件 datepicker被弹出框dialog覆盖的解决办法
2019/07/09 Javascript
基于canvasJS在PHP中制作动态图表
2020/05/30 Javascript
vue 虚拟DOM的原理
2020/10/03 Javascript
把MySQL表结构映射为Python中的对象的教程
2015/04/07 Python
使用Python装饰器在Django框架下去除冗余代码的教程
2015/04/16 Python
python中defaultdict的用法详解
2017/06/07 Python
python 使用值来排序一个字典的方法
2018/11/16 Python
python判断所输入的任意一个正整数是否为素数的两种方法
2019/06/27 Python
python 实现创建文件夹和创建日志文件的方法
2019/07/07 Python
Python简单实现区域生长方式
2020/01/16 Python
python实现全排列代码(回溯、深度优先搜索)
2020/02/26 Python
台湾线上百货零售购物平台:friDay购物
2017/08/18 全球购物
美国时尚在线:Showpo
2017/09/08 全球购物
ReVive利维肤美国官网:RéVive Skincare
2018/04/18 全球购物
土木工程毕业生自荐信
2013/11/12 职场文书
咖啡店自主创业商业计划书
2014/01/22 职场文书
烟台的海导游词
2015/02/02 职场文书
稽核岗位职责范本
2015/04/13 职场文书
2015年信息中心工作总结
2015/05/25 职场文书
2015年食品安全宣传周活动总结
2015/07/09 职场文书
Python利用zhdate模块实现农历日期处理
2022/03/31 Python