[TOC] >[success] # 什么是迭代器模式(菜鸟教程中代理模式总结) ~~~ 1.迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素, 而又不暴露该对象的内部表示。 2.主要解决:不同的方式来遍历整个整合对象。 3.何时使用:遍历一个聚合对象。 4.如何解决:把在元素之间游走的责任交给迭代器,而不是聚合对象 ~~~ >[danger] ##### 优缺点 * 优点 ~~~ 1、它支持以不同的方式遍历一个聚合对象。 2、迭代器简化了聚合类。 3、在同一个聚合上可以有多个遍历。 4、在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。 ~~~ * 缺点 ~~~ 1、由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类, 类的个数成对增加,这在一定程度上增加了系统的复杂性。 ~~~ >[danger]使用场景 ~~~ 1、访问一个聚合对象的内容而无须暴露它的内部表示。 2、需要为聚合对象提供多种遍历方式。 3、为遍历不同的聚合结构提供一个统一的接口。 ~~~ >[success] # 前端的代理模式 ~~~ 1.书中作者举了一个之前重构代码遇到的案例。并且将其重构成了迭代模式 2.更多的迭代使用在js中可以参考es6章节的迭代器 ~~~ >[danger] ##### 在这之前我要记录一个书中看到有意思代码块 ~~~ 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) }) ~~~ >[danger] ##### 书中作者遇到的案例 ~~~ 1.下面代码会针对不同浏览器来调用对应上传机制,代码违反一个原则封闭开放原则, 如果后续在有针对的下载机制需要接着在这个if...else 添加 2.用书中的话来说:目前一共有3种可能上传的方式,我们不知道目前正在使用的浏览器支持哪几种。 就好比我们有一个钥匙串,其中共有3把钥匙,我们想打开一扇门但是不知道用哪把钥匙, 于是从第一把开始,迭代钥匙串进行尝试,直到找到正确的钥匙为止。 ~~~ ~~~ var getUploadObj = function(){ try{ return new ActiveXObject(‘TXFINActiveX.FTNUpload”); //ie上传 }catch(e){ if(supportFlash()){ var str = '<object type="application/x-shockwave-flash"></object>'; return $(str).appendTo($('body')); }else{ var str = '<input name = "file" type="file"/>’ return $(str).appendTo($("body")); } } } ~~~ >[danger] ##### 改造后的代码 ~~~ 1.在上述的3个函数中我们都有同一个约定,如果该函数里面的upload对象是可用的, 则让函数返回该对象,反之返回false,提示迭代器继续往后进行迭代 ~~~ ~~~ var getActiveUploadObj = function(){ try{ return new ActiveXObject("TXFNActiveX.FTNUpload"); }catch(e){ return false; } } var getFlashUploadObj = function(){ if(supportFlash()){ var str = '<object type="application/x-shockwave-flash"></object>'; return $(str).appendTo($('body')); } return false; } var getFormUploadObj = function(){ var str = '<inputname ="file" type="file" />'; return$(str).appendTo($('body')); } ~~~ * 使用迭代 ~~~ 1.下面这个最终的优化调用感觉很像策略模式,但又和策略模式有了区别,策略是会在'Context' 根据条件选择要执行的策略,但是下面是全部循环没有具体情况直到找到自己想要的的对象 ~~~ ~~~ var iteratorUploadObj = function(){ for(var i=0,fn;fn=arguments[i++];){ var uploadObj =fn(); if(uploadObj!==false){ return uploadObj; } } } var uploadObj = iteratorUploadObj(getActiveUploadObj,getFlashUploadObj, getFormUploadObj); ~~~