学习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 相关文章推荐
JS中confirm,alert,prompt函数区别分析
Jan 17 Javascript
js的一些常用方法小结
Jun 29 Javascript
javascript的数据类型、字面量、变量介绍
May 23 Javascript
javaScript实现滚动新闻的方法
Jul 30 Javascript
jQuery与getJson结合的用法实例
Aug 07 Javascript
javascript巧用eval函数组装表单输入项为json对象的方法
Nov 25 Javascript
jQuery height()、innerHeight()、outerHeight()函数的区别详解
May 23 Javascript
webpack打包单页面如何引用的js
Jun 07 Javascript
vue.js的vue-cli脚手架中使用百度地图API的实例
Jan 21 Javascript
通过GASP让vue实现动态效果实例代码详解
Nov 24 Javascript
vue不操作dom实现图片轮播的示例代码
Dec 18 Javascript
最新最全的手机号验证正则表达式
Feb 24 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
模仿OSO的论坛(四)
2006/10/09 PHP
php adodb连接带密码access数据库实例,测试成功
2008/05/14 PHP
PHP上传文件时文件过大$_FILES为空的解决方法
2013/11/26 PHP
浅谈php命令行用法
2015/02/04 PHP
yii,CI,yaf框架+smarty模板使用方法
2015/12/29 PHP
php接口实现拖拽排序功能
2018/04/23 PHP
PHP7 foreach() 函数修改
2021/03/09 PHP
javascript 写类方式之七
2009/07/05 Javascript
JavaScript高级程序设计 扩展--关于动态原型
2010/11/09 Javascript
jQuery find和children方法使用
2011/01/31 Javascript
js获取html页面节点方法(递归方式)
2013/12/13 Javascript
基于javascript实现判断移动终端浏览器版本信息
2014/12/09 Javascript
jQuery使用hide方法隐藏页面上指定元素的方法
2015/03/30 Javascript
javascript中eval函数用法分析
2015/04/25 Javascript
轻量级javascript 框架Backbone使用指南
2015/07/24 Javascript
javascript常见数字进制转换实例分析
2016/04/21 Javascript
浅析Jquery操作select
2016/12/13 Javascript
js实现彩色条纹滚动条效果
2017/03/15 Javascript
json的结构与遍历方法实例分析
2017/04/25 Javascript
Vue.js获取手机系统型号、版本、浏览器类型的示例代码
2020/05/10 Javascript
JS常见内存泄漏及解决方案解析
2020/05/30 Javascript
JavaScript浅层克隆与深度克隆示例详解
2020/09/01 Javascript
Python清空文件并替换内容的实例
2018/10/22 Python
Django admin.py 在修改/添加表单界面显示额外字段的方法
2019/08/22 Python
Python requests模块基础使用方法实例及高级应用(自动登陆,抓取网页源码)实例详解
2020/02/14 Python
windows下Pycharm安装opencv的多种方法
2020/03/05 Python
django模板获取list中指定索引的值方式
2020/05/14 Python
利用django创建一个简易的博客网站的示例
2020/09/29 Python
HTML5中原生的右键菜单创建方法
2016/06/28 HTML / CSS
法国时尚童装网站:Melijoe
2016/08/10 全球购物
全球异乡人的跨境社交电商平台:Kouhigh口嗨网
2020/07/24 全球购物
岳父生日宴会答谢词
2014/01/13 职场文书
车辆工程专业求职信
2014/06/14 职场文书
人事专员岗位职责
2015/02/03 职场文书
天河观后感
2015/06/11 职场文书
Mysql中调试存储过程最简单的方法
2021/06/30 MySQL