学习JavaScript设计模式之迭代器模式
脚本之家 / 编程助手:解决程序员“几乎”所有问题!
脚本之家官方知识库 → 点击立即使用
- 迭代器模式是指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。
JavaScript中的Array.prototype.forEach
一、jQuery中的迭代器
二、实现自己的迭代器
1 2 3 4 5 6 7 8 | 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 | [1, 2, 3].forEach( function (n, i, curAry){ console.log( "当前下标为:" + i + " 当前元素为:" + n + " 当前数组为:" + curAry); }) |
三、内部迭代器、外部迭代器
(1)内部迭代器:已经定义好了迭代规则,它完全接手整个迭代过程,外部只需一次初始调用。上述自定义each即为内部迭代器!
(2)外部迭代器:必须显示地请求迭代下一个元素。
示例:判断两个数组是否相等
示例一:内部迭代器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | // 内部迭代器 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]); |
示例二:外部迭代器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | // 外部迭代器 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])); |
四、终止迭代器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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设计模式–责任链模式》
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | 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上下方向键控制表格行选中并高亮显示的方法
这篇文章主要介绍了javascript上下方向键控制表格行选中并高亮显示的方法,涉及javascript针对键盘按键操作相应的技巧,具有一定参考借鉴价值,需要的朋友可以参考下2015-02-02详解webpack-dev-server使用http-proxy解决跨域问题
这篇文章主要介绍了详解webpack-dev-server使用http-proxy解决跨域问题,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧2018-01-01JavaScript setTimeout和setInterval的用法与区别详解
Javascript的setTimeOut和setInterval函数应用非常广泛,它们都用来处理延时和定时任务,下面这篇文章主要给大家介绍了关于JavaScript setTimeout和setInterval的用法与区别,需要的朋友可以参考下2022-04-04
最新评论