学习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 &amp; DHTML 实例编程(教程)DOM基础和基本API
Jun 02 Javascript
JavaScript让IE浏览器event对象符合W3C DOM标准
Nov 24 Javascript
javascript正则表达式中的replace方法详解
Apr 20 Javascript
jQuery flip插件实现的翻牌效果示例【附demo源码下载】
Sep 20 Javascript
利用Node.js+Koa框架实现前后端交互的方法
Feb 27 Javascript
详解vuejs之v-for列表渲染
Jun 22 Javascript
jQuery实现checkbox即点即改批量删除及中间遇到的坑
Nov 11 jQuery
关于HTTP传输中gzip压缩的秘密探索分析
Jan 12 Javascript
对类Vue的MVVM前端库的实现代码
Sep 07 Javascript
使用微信小程序开发弹出框应用实例详解
Oct 18 Javascript
Vue分页插件的前后端配置与使用
Oct 09 Javascript
Vue是怎么渲染template内的标签内容的
Jun 05 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模拟QQ登录的方法
2015/07/29 PHP
Yii2中datetime类的使用
2016/12/17 PHP
用 javascript 实现的点击复制代码
2007/03/24 Javascript
基于JQuery实现异步刷新的代码(转载)
2011/03/29 Javascript
用js的for循环获取radio选中的值
2013/10/21 Javascript
jQuery-1.9.1源码分析系列(十)事件系统之事件体系结构
2015/11/19 Javascript
Javascript中indexOf()和lastIndexOf应用方法实例
2016/08/24 Javascript
在JSP中如何实现MD5加密的方法
2016/11/02 Javascript
js css3实现图片拖拽效果
2017/03/04 Javascript
使用requirejs模块化开发多页面一个入口js的使用方式
2017/06/14 Javascript
Vue.JS实现垂直方向展开、收缩不定高度模块的JS组件
2018/06/19 Javascript
使用FormData实现上传多个文件
2018/12/04 Javascript
JS实现在线ps功能详解
2019/07/31 Javascript
Vue-CLI 项目在pycharm中配置方法
2019/08/30 Javascript
Vue实现开心消消乐游戏算法
2019/10/22 Javascript
vue动态设置页面title的方法实例
2020/08/23 Javascript
js轮播图之旋转木马效果
2020/10/13 Javascript
浅谈Python程序与C++程序的联合使用
2015/04/07 Python
python通过get,post方式发送http请求和接收http响应的方法
2015/05/26 Python
python机器学习理论与实战(六)支持向量机
2018/01/19 Python
为什么选择python编程语言入门黑客攻防 给你几个理由!
2018/02/02 Python
python读取文本绘制动态速度曲线
2018/06/21 Python
详解如何在Apache中运行Python WSGI应用
2019/01/02 Python
Laravel框架表单验证格式化输出的方法
2019/09/25 Python
Python字典底层实现原理详解
2019/12/18 Python
法国二手手袋、手表和奢侈珠宝购物网站:Collector Square
2018/07/05 全球购物
小学毕业演讲稿
2014/04/25 职场文书
租房协议书样本
2014/08/20 职场文书
防灾减灾日活动总结
2014/08/26 职场文书
社保代办委托书怎么写
2014/10/06 职场文书
公司领导班子召开党的群众路线教育实践活动总结大会新闻稿
2014/10/21 职场文书
机关党员四风问题个人整改措施
2014/10/26 职场文书
安全员岗位职责
2015/02/10 职场文书
自主招生自荐信格式范文
2015/03/25 职场文书
学校食堂管理制度
2015/08/04 职场文书
MySQL 全文检索的使用示例
2021/06/07 MySQL