摘要:迭代器模式就是按照順序訪問(wèn)一個(gè)對(duì)象中元素,而不用暴露該對(duì)象的內(nèi)部組成。迭代器模式就是將這個(gè)迭代實(shí)現(xiàn)從業(yè)務(wù)中分離出來(lái)。外部迭代器外部迭代器必須顯式地請(qǐng)求才會(huì)迭代下一個(gè)元素。
迭代器模式就是按照順序訪問(wèn)一個(gè)對(duì)象中元素,而不用暴露該對(duì)象的內(nèi)部組成。迭代器模式就是將這個(gè)迭代實(shí)現(xiàn)從業(yè)務(wù)中分離出來(lái)。
但實(shí)際開(kāi)發(fā)中我們并不將他當(dāng)成一個(gè)設(shè)計(jì)模式。
前瞻后顧說(shuō)起迭代器,想必對(duì)ES6有了解的同學(xué)應(yīng)該不會(huì)陌生。我們知道,for ... of 遍歷的對(duì)象必須是迭代器對(duì)象,而普通對(duì)象則不能,因?yàn)槠胀▽?duì)象內(nèi)部沒(méi)有實(shí)現(xiàn)迭代器,而像數(shù)組則內(nèi)部實(shí)現(xiàn)了迭代器,所以可以用for ... of 的語(yǔ)法,而對(duì)于一般對(duì)象在ES5中有專門(mén)的處理方法,for ... in 和
Object.keys() ,而 for ... in 可遍歷所有的的對(duì)象,但是它遍歷特殊對(duì)象,如數(shù)組,也會(huì)遍歷它的length,這并不是我們需要的,有時(shí)還會(huì)出現(xiàn)不按順序的遍歷。
在我們?nèi)粘J褂弥幸话闶菍⑵胀▽?duì)象轉(zhuǎn)化為特殊對(duì)象然后處理的。
仿jQuery迭代器這里我只簡(jiǎn)單的實(shí)現(xiàn)數(shù)組的遍歷,至于如何迭代普通對(duì)象,我們下面再做介紹。
var $ = { each: function (arr, fn) { for (var i = 0, len = arr.length; i < len; i++) { fn.call(arr[i], i, arr[i]) } } }; $.each([1, 2, 3, 4, 5, 6], function(i, val) { console.log([i, val]); });迭代器的分類
迭代器根據(jù)實(shí)現(xiàn)的位置,我們將它分為內(nèi)部迭代器和外部迭代器兩種。
內(nèi)部迭代器內(nèi)部迭代器對(duì)于使用者來(lái)說(shuō)他不用關(guān)心迭代器的內(nèi)部實(shí)現(xiàn),只用關(guān)注使用的效果,我們上面仿jQuery的each就是個(gè)內(nèi)部迭代器的實(shí)現(xiàn)。
內(nèi)部迭代器有它的好處但是也有它的不足,比如我們要比較兩個(gè)數(shù)組是否相等,上面的方法就不滿足我們的需要,我們就需要寫(xiě)一個(gè)新的方法來(lái)實(shí)現(xiàn)。
var $ = { each: function (arr, fn) { for (var i = 0, len = arr.length; i < len; i++) { fn.call(arr[i], i, arr[i]) } } }; var compareArray = function(arr, arr2) { if( arr.length !== arr2.length) { return false; } $.each(arr, function(i, val) { if( val !== arr2[i]) { return false; } }); return true; }; compareArray([1, 2], [1, 2, 3]); // false外部迭代器
外部迭代器必須顯式地請(qǐng)求才會(huì)迭代下一個(gè)元素。
外部迭代器雖然增加了使用上的一些麻煩,但是它的靈活性卻正是我們需要的。我們可以人為的控制迭代的過(guò)程和順序。
// 迭代器實(shí)現(xiàn) var Iterator = function(obj) { var current = 0; var next = function() { current += 1; }; var isDone = function() { return current >= obj.length; }; var getCurrItem = function() { return obj[current]; }; var len = function() { return obj.length; } return { next: next, isDone: isDone, getCurrItem: getCurrItem, length: len, } }; // 比較數(shù)組 var compareArray = function (iteratorObj, iteratorObj2) { if(iteratorObj.length !== iteratorObj2.length) { return false; } while (!iteratorObj.isDone() && !iteratorObj2.isDone()){ if (iteratorObj.getCurrItem() !== iteratorObj2.getCurrItem()){ return false; } iteratorObj.next(); iteratorObj2.next(); } return true; }; var arr = Iterator([1, 2, 3]); var arr2 = Iterator([1, 2, 3]); compareArray(arr, arr2); // true
這樣我們就用ES5實(shí)現(xiàn)了迭代器的功能,ES6的實(shí)現(xiàn)迭代器相對(duì)簡(jiǎn)單,如果不熟悉的可以參考一下阮一峰老師的 ES6 使用手冊(cè)
迭代對(duì)象使用ES6迭代器后發(fā)現(xiàn),for ... of 能夠遍歷的迭代器對(duì)象,如: 數(shù)組,類數(shù)組,Set,Map,arguments等對(duì)象它們有一個(gè)共同的特性,就是它們都有一個(gè)length數(shù)組,可以實(shí)現(xiàn)對(duì)對(duì)象用下標(biāo)進(jìn)行訪問(wèn)。
因此,要實(shí)現(xiàn)對(duì)普通對(duì)象的的迭代,我們可以參考jQuery的實(shí)現(xiàn)如下做:
var isArraylike = function(obj) { return Object.prototype.toString.call(obj) === [object Array]; } $ = { each: function(obj, fn) { var isArray = isArraylike(obj); // 判斷對(duì)象是否為數(shù)組 if (isArray) { for (var i = 0, len = obj.length ; i < len; i++ ) { if (fn.call(obj[i], i, obj[i]) === false) { break; } } } else { for (i in obj) { if (fn.call(obj[i], i, obj[i]) === false) { break; } } } } };
我們?cè)偈褂肊S6處理一般對(duì)象時(shí)一般使用兩種方法,一種是將普通對(duì)象轉(zhuǎn)化為迭代器對(duì)象,另一種就是上面這種寫(xiě)法。
設(shè)計(jì)模式周周講
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/92732.html
摘要:文章內(nèi)容分兩部分前半部分為迭代器模式概念后半部分為中迭代器上半部分開(kāi)始迭代器模式提供一種方法順序訪問(wèn)一個(gè)聚合對(duì)象中的各個(gè)元素,而又不需要暴露該對(duì)象的內(nèi)部表示。下半部分開(kāi)始的迭代器迭代器等同于遍歷器。執(zhí)行該函數(shù),會(huì)返回一個(gè)遍歷器對(duì)象。 showImg(https://segmentfault.com/img/bVbuyaZ?w=800&h=600); 文章內(nèi)容分兩部分: 前半部分為 迭...
摘要:本文已同步到中常見(jiàn)的設(shè)計(jì)模式如果感覺(jué)寫(xiě)的還可以,就給個(gè)小星星吧,歡迎和收藏。本文中關(guān)于各種設(shè)計(jì)模式定義都是引用書(shū)中的,部分引用自百度百科已標(biāo)出。下面把我整理出的常用設(shè)計(jì)模式按類型做個(gè)表格整理。 本文已同步到Github JavaScript中常見(jiàn)的設(shè)計(jì)模式,如果感覺(jué)寫(xiě)的還可以,就給個(gè)小星星吧,歡迎star和收藏。 最近拜讀了曾探大神的《JavaScript設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐》,真是醍醐...
摘要:所以自己動(dòng)手用重新實(shí)現(xiàn)了一遍里面的設(shè)計(jì)模式,算是對(duì)其的鞏固,也算是與大家一起來(lái)研究探討語(yǔ)法的一些最佳實(shí)踐。 前言 最近在回顧設(shè)計(jì)模式方式的知識(shí),重新翻閱了《JavaScript模式》(個(gè)人感覺(jué)也算是一本小有名氣的書(shū)了哈)一書(shū),讀時(shí)總有感觸:在即將到來(lái)的ES6的大潮下,書(shū)中的許多模式的代碼可用ES6的語(yǔ)法更為優(yōu)雅簡(jiǎn)潔的實(shí)現(xiàn),而另一些模式,則已經(jīng)被ES6原生支持,如模塊模式(99頁(yè))。所...
摘要:命令模式的由來(lái),其實(shí)是回調(diào)函數(shù)的一個(gè)面向?qū)ο蟮奶娲罚钅J皆缫讶谌氲搅苏Z(yǔ)言之中。 模式是對(duì)某情景下,針對(duì)某種問(wèn)題的某種解決方案。而一個(gè)設(shè)計(jì)模式是用來(lái)解決一個(gè)經(jīng)常出現(xiàn)的設(shè)計(jì)問(wèn)題的經(jīng)驗(yàn)方法。這么說(shuō)來(lái),每個(gè)模式都可能有著自己的意圖,應(yīng)用場(chǎng)景,使用方法和使用后果。本文的行文思路和目的皆在于了解各個(gè)模式的定義,應(yīng)用場(chǎng)景和用實(shí)例說(shuō)明如何在前端開(kāi)發(fā)中使用。 本文所設(shè)計(jì)到的概念和實(shí)例大多來(lái)自《H...
摘要:為了使程序員能夠一次一個(gè)地處理集合中的元素,引入了迭代器接口。迭代器使用該方法獲取對(duì)象屬性名稱的數(shù)組,然后將其分配給常量。迭代器的缺點(diǎn)是它們不適合表示異步數(shù)據(jù)源。每次循環(huán)時(shí),都會(huì)調(diào)用迭代器的方法,它返回一個(gè)。 前言 原文地址:https://css-tricks.com/new-es2018-features-every-javascript-developer-should-kno...
閱讀 888·2021-11-15 11:38
閱讀 2519·2021-09-08 09:45
閱讀 2819·2021-09-04 16:48
閱讀 2569·2019-08-30 15:54
閱讀 935·2019-08-30 13:57
閱讀 1623·2019-08-29 15:39
閱讀 501·2019-08-29 12:46
閱讀 3525·2019-08-26 13:39