学习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的日期格式化算法示例
Jul 31 Javascript
浏览器窗口大小变化时使用resize事件对框架不起作用的解决方法
May 11 Javascript
javascript制作网页图片上实现下雨效果
Feb 26 Javascript
JS实现简易图片轮播效果的方法
Mar 25 Javascript
Jquery实现鼠标移动放大图片功能实例
Mar 25 Javascript
jquery马赛克拼接翻转效果代码分享
Aug 24 Javascript
10个JavaScript中易犯小错误
Feb 14 Javascript
node.js实现博客小爬虫的实例代码
Oct 08 Javascript
可输入文字查找ajax下拉框控件 ComBox的实现方法
Oct 25 Javascript
对node.js中render和send的用法详解
May 14 Javascript
jQuery中将json数据显示到页面表格的方法
May 27 jQuery
JS如何寻找数组中心索引过程解析
Jun 01 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
什么是MVC,好东西啊
2007/05/03 PHP
php获取目录所有文件并将结果保存到数组(实例)
2013/10/25 PHP
PHP错误和异长常处理总结
2014/03/06 PHP
浅谈PHP正则表达式中修饰符/i, /is, /s, /isU
2014/10/21 PHP
php实现window平台的checkdnsrr函数
2015/05/27 PHP
php 如何禁用eval() 函数实例详解
2016/12/01 PHP
PHP实现一个轻量级容器的方法
2019/01/28 PHP
Javascript之文件操作
2007/03/07 Javascript
WordPress 插件——CoolCode使用方法与下载
2007/07/02 Javascript
javascript内存管理详细解析
2013/11/11 Javascript
jquery统计输入文字的个数并对其进行判断
2014/01/07 Javascript
jQuery表单验证功能实例
2015/08/28 Javascript
js获取图片宽高的方法
2015/11/25 Javascript
Bootstrap进度条组件知识详解
2016/05/01 Javascript
jQuery实现花式轮播之圣诞节礼物传送效果
2016/12/25 Javascript
Node.js 中exports 和 module.exports 的区别
2017/03/14 Javascript
nodejs入门教程一:概念与用法简介
2017/04/24 NodeJs
jQuery判断网页是否已经滚动到浏览器底部的实现方法
2017/10/27 jQuery
JS实现仿微信支付弹窗功能
2018/06/25 Javascript
js实现的订阅发布者模式简单示例
2020/03/14 Javascript
Javascript基于OOP实实现探测器功能代码实例
2020/08/26 Javascript
Vue中使用Echarts仪表盘展示实时数据的实现
2020/11/01 Javascript
分析Python中解析构建数据知识
2018/01/20 Python
Python3 实现随机生成一组不重复数并按行写入文件
2018/04/09 Python
python操作kafka实践的示例代码
2019/06/19 Python
用Python实现二叉树、二叉树非递归遍历及绘制的例子
2019/08/09 Python
Python reshape的用法及多个二维数组合并为三维数组的实例
2020/02/07 Python
Keras自定义实现带masking的meanpooling层方式
2020/06/16 Python
一文详述 Python 中的 property 语法
2020/09/01 Python
python GUI计算器的实现
2020/10/09 Python
python输出国际象棋棋盘的实例分享
2020/11/26 Python
新奇的小玩意:IWOOT
2016/07/21 全球购物
C,C++的几个面试题小集
2013/07/13 面试题
中文系师范生自荐信
2013/10/01 职场文书
我心目中的好老师活动方案
2014/08/19 职场文书
php修改word的实例方法
2021/11/17 PHP