学习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中escape对应的C#解码函数 UrlDecode
Dec 16 Javascript
一些常用弹出窗口/拖放/异步文件上传等实用代码
Jan 06 Javascript
js中eval()函数和trim()去掉字符串左右空格应用
Feb 02 Javascript
取消选中单选框radio的三种方式示例介绍
Dec 23 Javascript
Angular 常用指令实例总结整理
Dec 13 Javascript
详解JS中统计函数执行次数与执行时间
Sep 04 Javascript
了解JavaScript中let语句
May 30 Javascript
详解javascript中var与ES6规范中let、const区别与用法
Jan 11 Javascript
JS 创建对象的模式实例小结
Apr 28 Javascript
jQuery实现移动端下拉展现新的内容回弹动画
Jun 24 jQuery
vue中的v-model原理,与组件自定义v-model详解
Aug 04 Javascript
javascript贪吃蛇游戏设计与实现
Sep 17 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实现MVC开发得最简单的方法――模型
2007/04/10 PHP
php flv视频时间获取函数
2010/06/29 PHP
通过PHP设置BugFree获取邮箱通知
2019/04/25 PHP
解决laravel资源加载路径设置的问题
2019/10/14 PHP
greybox——不开新窗口看新的网页
2007/02/20 Javascript
javascript web页面刷新的方法收集
2009/07/02 Javascript
最新28个很棒的jQuery 教程
2011/05/28 Javascript
使用canvas实现仿新浪微博头像截取上传功能
2015/09/02 Javascript
简单实现js进度条加载效果
2020/03/25 Javascript
jQuery响应滚动条事件功能示例
2017/10/14 jQuery
小程序实现分类页
2019/07/12 Javascript
layui table 获取分页 limit的方法
2019/09/20 Javascript
Python 正则表达式实现计算器功能
2017/04/29 Python
Python中函数及默认参数的定义与调用操作实例分析
2017/07/25 Python
利用pyinstaller将py文件打包为exe的方法
2018/05/14 Python
Python 字符串转换为整形和浮点类型的方法
2018/07/17 Python
Flask-Mail用法实例分析
2018/07/21 Python
Flask框架URL管理操作示例【基于@app.route】
2018/07/23 Python
python将控制台输出保存至文件的方法
2019/01/07 Python
python 自定义装饰器实例详解
2019/07/20 Python
Python argparse模块使用方法解析
2020/02/20 Python
python数据预处理 :数据共线性处理详解
2020/02/24 Python
Django实现从数据库中获取到的数据转换为dict
2020/03/27 Python
随机分配座位,共50个学生,使学号相邻的同学座位不能相邻
2014/01/18 面试题
升国旗仪式主持词
2014/03/19 职场文书
基层党组织整改方案
2014/10/25 职场文书
幼儿园法制宣传日活动总结
2014/11/01 职场文书
个人学习党的群众路线教育实践活动心得体会
2014/11/05 职场文书
爱国主义教育基地观后感
2015/06/18 职场文书
《鸟的天堂》教学反思
2016/02/19 职场文书
如何写好闭幕词
2019/04/02 职场文书
MySQL命令行操作时的编码问题详解
2021/04/14 MySQL
详解JVM系列之内存模型
2021/06/10 Javascript
详解python网络进程
2021/06/15 Python
MySQL中存储时间的最佳实践指南
2021/07/01 MySQL
Python中使用tkFileDialog实现文件选择、保存和路径选择
2022/05/20 Python