迭代器模式
定义:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。
应用:jQuery 中的\$.each 函数、forEach 内置迭代器、根据不同情况执行不同的函数
分类:
- 内部迭代器
定义迭代规则,完全接手整个迭代过程,外部只需要一次初试调用,不需要关心迭代器内部实现,上面的 each 函数就属于内部迭代器。
- 外部迭代器
必须显式地请求迭代下一个元素,增加了调用复杂度,但是增强了迭代器的灵活性,可以手工控制迭代的过程或者顺序。
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
| const Iterator = obj => { let current = 0; const next = () => { current += 1; }; const isDone = () => { return current >= obj.length; }; const getCurrItem = () => { return obj[current]; }; return { next, isDone, getCurrItem, length: obj.length }; };
const compare = (iterator1, iterator2) => { if (iterator1.length !== iterator2.length) { return false; } while (!iterator1.isDone() && !iterator2.isDone()) { if (iterator1.getCurrItem() !== iterator2.getCurrItem()) { return false; } iterator1.next(); iterator2.next(); } return true; };
const iterator1 = Iterator([1, 2, 3]); const iterator2 = Iterator([1, 2, 3]); compare(iterator1, iterator2);
|
实现:
实现自己的迭代器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| const each = (array, callback) => { for (let i = 0, l = array.length; i < l; i++) { if (callback(i, array[i]) === false) { break; } } }; each([1, 2, 3], (i, n) => { if (n === 2) { return false; } console.log(i, n); });
|
根据不同的浏览器获取相应的上传组件对象
实现思路:普通方法使用 try-catch 和 if-else 实现,但是如果增加了别的上传方式,就要改变原函数的条件分支。改造成,每种获取 upload 对象的方法都封装在各自的函数中,使用迭代器获取 upload 对象,直到获取到一个可用的为止。
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
| const getActiveUploadObj = () => { try { return new ActiveXObject('TXFTNActiveX.FTNUpload'); } catch (e) { return false; } };
const getFlashUploadObj = () => { if (supportFlash()) { const str = '<object type="application/x-shockwave-flash"></object>'; return $(str).appendTo($('body')); } return false; };
const getFormUpladObj = () => { const str = '<input name="file" type="file" class="ui-file"/>'; return $(str).appendTo($('body')); };
const iteratorUploadObj = () => { for (let i = 0, fn; (fn = arguments[i++]); ) { const uploadObj = fn(); if (uploadObj !== false) { return uploadObj; } } };
const uploadObj = iteratorUploadObj(getActiveUploadObj, getFlashUploadObj, getFormUpladObj);
|
aaaa啊啊啊