学习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 相关文章推荐
jQuery 下拉列表 二级联动插件分享
Mar 29 Javascript
jcrop基本参数一览
Jul 16 Javascript
JavaScript判断表单中多选框checkbox选中个数的方法
Aug 17 Javascript
跟我学习javascript的异步脚本加载
Nov 20 Javascript
详解Javascript函数声明与递归调用
Oct 22 Javascript
使用ionic在首页新闻中应用到的跑马灯效果的实现方法
Feb 13 Javascript
Input文本框随着输入内容多少自动延伸的实现
Feb 15 Javascript
vue中手机号,邮箱正则验证以及60s发送验证码的实例
Mar 16 Javascript
React路由管理之React Router总结
May 10 Javascript
详解微信小程序开发之formId使用(模板消息)
Aug 27 Javascript
JavaScript中变量提升和函数提升的详解
Aug 07 Javascript
vue自定义插件封装,实现简易的elementUi的Message和MessageBox的示例
Nov 20 Vue.js
学习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
WordPress中转义HTML与过滤链接的相关PHP函数使用解析
2015/12/22 PHP
总结PHP如何获取当前主机、域名、网址、路径、端口和参数等
2016/09/09 PHP
PHP实现的大文件切割与合并功能示例
2018/04/10 PHP
ThinkPHP5.0 图片上传生成缩略图实例代码说明
2018/06/20 PHP
JQuery复制DOM节点的方法
2015/06/11 Javascript
js实现浏览本地文件并显示扩展名的方法
2015/08/17 Javascript
jQuery中cookie插件用法实例分析
2015/12/04 Javascript
Angular ng-repeat 对象和数组遍历实例
2016/09/14 Javascript
jquery封装插件时匿名函数形参和实参的写法解释
2017/02/14 Javascript
AngularJS实现进度条功能示例
2017/07/05 Javascript
微信小程序实现MUI数字输入框效果
2018/01/31 Javascript
vue基于mint-ui实现城市选择三级联动
2020/06/30 Javascript
vue路由事件beforeRouteLeave及组件内定时器的清除方法
2018/09/29 Javascript
详解vue 自定义组件使用v-model 及探究其中原理
2019/10/11 Javascript
vue新建项目并配置标准路由过程解析
2019/12/09 Javascript
简单介绍利用TK在Python下进行GUI编程的教程
2015/04/13 Python
Python读写配置文件的方法
2015/06/03 Python
python bottle框架支持jquery ajax的RESTful风格的PUT和DELETE方法
2017/05/24 Python
Python实现加载及解析properties配置文件的方法
2018/03/29 Python
numpy添加新的维度:newaxis的方法
2018/08/02 Python
python斐波那契数列的计算方法
2018/09/27 Python
一文了解Python并发编程的工程实现方法
2019/05/31 Python
python 实现线程之间的通信示例
2020/02/14 Python
keras Lambda自定义层实现数据的切片方式,Lambda传参数
2020/06/11 Python
Python 爬虫的原理
2020/07/30 Python
一个非常简单好用的Python图形界面库(PysimpleGUI)
2020/12/28 Python
婚礼新郎父母答谢词
2014/01/16 职场文书
大学生优秀自荐信范文
2014/02/25 职场文书
新学期决心书
2014/03/11 职场文书
3分钟英语演讲稿
2014/04/29 职场文书
企业文明单位申报材料
2014/05/16 职场文书
合作合同协议书范本
2015/01/27 职场文书
人事任命通知书
2015/04/21 职场文书
Python爬虫爬取全球疫情数据并存储到mysql数据库的步骤
2021/03/29 Python
详解Java实践之建造者模式
2021/06/18 Java/Android