摘要:簡(jiǎn)單介紹下規(guī)范里面迭代器相關(guān)的概念。接口指定迭代器對(duì)象必須實(shí)現(xiàn)一個(gè)方法,如下示例偽代碼。方法是否接受參數(shù),在規(guī)范中并不嚴(yán)格限定,取決于實(shí)現(xiàn)當(dāng)前這個(gè)迭代器的對(duì)象。表示迭代終結(jié),后續(xù)再調(diào)用當(dāng)前迭代器的方法,返回的對(duì)象一律為。
簡(jiǎn)單介紹下 ES6 規(guī)范里面迭代器(Iterator)相關(guān)的概念。最近為啥會(huì)看到迭代器,是因?yàn)榭戳?fetch 相關(guān)的 Headers 接口,為了實(shí)現(xiàn)下 Headers 接口就涉及到了迭代器。
迭代器(Iterator)為什么要有迭代器,是為了給不同的數(shù)據(jù)結(jié)構(gòu)一個(gè)統(tǒng)一的迭代方法,不管你是一個(gè) Array 還是一個(gè) Queue 還是一個(gè) Dictionary,反正只要你提供了符合規(guī)范的迭代器,程序員就能通過(guò)統(tǒng)一的方法來(lái)迭代你這個(gè)數(shù)據(jù)結(jié)構(gòu)。迭代器是一個(gè)實(shí)現(xiàn)了 Iterator 接口的對(duì)象。接口指定迭代器對(duì)象必須實(shí)現(xiàn)一個(gè) next 方法,如下示例偽代碼。
var iterator = { next: function() { // impl } }
next 方法是否接受參數(shù),在規(guī)范中并不嚴(yán)格限定,取決于實(shí)現(xiàn)當(dāng)前這個(gè)迭代器的對(duì)象。但是必須能接受無(wú)參數(shù)的情況,因?yàn)?ES6 語(yǔ)法使用迭代器的時(shí)候是不會(huì)傳參數(shù)的,譬如 for-of。next 方法返回的數(shù)據(jù)結(jié)構(gòu)是 {done:boolean, value:ES6value}。每次調(diào)用 next,如果與之關(guān)聯(lián)的數(shù)據(jù)結(jié)構(gòu)里面有數(shù)據(jù),那么按照當(dāng)前數(shù)據(jù)結(jié)構(gòu)自己的規(guī)則把當(dāng)前被迭代到的元素放到返回的數(shù)據(jù)結(jié)構(gòu)的 value 值中,done 填寫(xiě) false。done 標(biāo)識(shí)是否迭代到了最后。當(dāng)?shù)阶詈笠粋€(gè)元素后,再調(diào)用一次 next 后,返回的 done 就應(yīng)該是 true。用代碼示例下:
function getArrayIterator( array ) { // 等下再說(shuō) } var iterator = getArrayIterator( [1, 2, 3, 4] ); iterator.next(); // { done: false, value: 1 } iterator.next(); // { done: false, value: 2 } iterator.next(); // { done: false, value: 3 } iterator.next(); // { done: false, value: 4 } iterator.next(); // { done: true, value: undefined } iterator.next(); // { done: true, value: undefined }
當(dāng)?shù)饕呀?jīng)迭代完最后一個(gè)元素,那么無(wú)論調(diào)用幾次 next 返回的 done 都是 true。不過(guò)規(guī)范里面說(shuō),如果在迭代的過(guò)程中,next 返回的數(shù)據(jù)結(jié)構(gòu)中沒(méi)有 done 這個(gè)屬性的話,我們應(yīng)該視作其值是 false。再來(lái)看看 value,其取值可以是規(guī)范中的任意類型。當(dāng)?shù)阶詈笠粋€(gè)元素后,即 done:true 的時(shí)候,value 可以是 undefined,也可以被填入一個(gè)返回值。MDN 中加了一篇文章的鏈接來(lái)說(shuō)明當(dāng) done:true 時(shí)候,value 如果被設(shè)成有一個(gè) returnValue 的意義,不過(guò)我英語(yǔ)比較挫真心沒(méi)有看懂,只能列下原文引用:
可迭代對(duì)象(Iterable)Why can iterators (optionally) return a value after the last element? That capability is the reason for elements being wrapped. Otherwise, iterators could simply return a publicly defined sentinel (stop value) after the last element.
迭代器是通過(guò)可迭代對(duì)象獲得的,譬如數(shù)組就是一個(gè)可迭代對(duì)象。那么如何通過(guò)可迭代對(duì)象獲得迭代器呢?規(guī)范中規(guī)定可迭代對(duì)象必須實(shí)現(xiàn)一個(gè)名為 @@iterator 的方法,調(diào)用這個(gè)方法返回和當(dāng)前對(duì)象掛鉤的迭代器,譬如:
function getArrayIterator( array ) { return array[ "@@iterator" ](); } var iterator = getArrayIterator( [1, 2, 3, 4] );
但是 @@iterator 方法的名字并不是一個(gè) string,而是 Symbol.iterator。Symbol 是ES6 引入的一個(gè)新的類型,表示一個(gè)獨(dú)一無(wú)二的值(這里就不展開(kāi)了)。所以上例獲取迭代器不是正確的寫(xiě)法,正確的應(yīng)該是:
function getArrayIterator( array ) { return array[ Symbol.iterator ](); } var iterator = getArrayIterator( [1, 2, 3, 4] );
ES6 中新加了一些針對(duì)可迭代對(duì)象的語(yǔ)法,譬如 for-of:
var array = [ 1, 2, 3 ]; for ( let i of array ) { console.log( i ); } // 輸出 // 1 // 2 // 3 /* 上面的 for-of 和下面的代碼等價(jià) */ var iterator = array[ Symbol.iterator ](); var iteratorResult = iterator.next(); while( !iteratorResult.done ) { console.log( iteratorResult.value ); iteratorResult = iterator.next(); }迭代器(Iterator)可選屬性
其實(shí)迭代器除了規(guī)定一定要實(shí)現(xiàn)的 next 方法,還有兩個(gè)是可選實(shí)現(xiàn)的方法 return 和 throw。
returnreturn 方法如果被調(diào)用,意味著調(diào)用者要終結(jié)此次迭代。return 返回一個(gè) {done:true, value:arg} 對(duì)象,value 是調(diào)用 return 方法時(shí)傳入的參數(shù),即:
var iterator = { next: function() { // impl }, return: function( arg ) { return { done: true, value: arg } } }
return 方法被調(diào)用后,后續(xù)再調(diào)用當(dāng)前迭代器的 next 方法,返回的對(duì)象 done 一律為 true。
throwthrow 方法如果被調(diào)用,表示迭代的過(guò)程中檢測(cè)到了異常。一般來(lái)說(shuō) throw 方法傳入的參數(shù)就是錯(cuò)誤對(duì)象(但是這個(gè)不是強(qiáng)制規(guī)定的)。throw 方法的通常行為應(yīng)該是以拋出異常的方式拋出傳入的對(duì)象,但是這個(gè)行為也是建議不強(qiáng)制。如果 throw 方法不拋出異常,那么返回值為 {done:true}。表示迭代終結(jié),后續(xù)再調(diào)用當(dāng)前迭代器的 next 方法,返回的對(duì)象 done 一律為 true。
因?yàn)?return 和 throw 兩個(gè)方法是可選實(shí)現(xiàn)的,所以在調(diào)用迭代器這個(gè)兩個(gè)方法前,都要檢測(cè)這兩個(gè)方法是否存在。
補(bǔ)充:
規(guī)范里面指出,迭代器也必須是一個(gè)可迭代的對(duì)象,即:
iterator = { next: function() { }, [Symbol.iterator]: function() { return this; } }
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/83100.html
摘要:我們將從概念上理解迭代器是什么,以及在何處使用它們和示例。同時(shí)返回一個(gè)名為迭代器的對(duì)象,這個(gè)迭代器將擁有一個(gè)名為的方法,該方法將返回一個(gè)具有鍵值為和的對(duì)象。下圖可以幫助建立可迭代對(duì)象迭代器和之間的關(guān)系,這種關(guān)系稱為迭代協(xié)議。 showImg(https://segmentfault.com/img/bVbkk18?w=1000&h=562); 我們將在本文中分析迭代器。迭代器是在Jav...
摘要:更新了個(gè)版本,最新正式版是語(yǔ)言的下一代標(biāo)準(zhǔn),早已在年月正式發(fā)布?;静恢С忠苿?dòng)端瀏覽器對(duì)的支持情況版起便可以支持的新特性。比較通用的工具方案有,,,等。 1、ECMAScript是什么? 和 JavaScript 有著怎樣的關(guān)系? 1996 年 11 月,Netscape 創(chuàng)造了javascript并將其提交給了標(biāo)準(zhǔn)化組織 ECMA,次年,ECMA 發(fā)布 262 號(hào)標(biāo)準(zhǔn)文件(ECMA-...
摘要:擴(kuò)展運(yùn)算符簡(jiǎn)介擴(kuò)展運(yùn)算符是三個(gè)點(diǎn),可以將一個(gè)數(shù)組轉(zhuǎn)為用逗號(hào)分隔的參數(shù)序列。在實(shí)際項(xiàng)目中靈活應(yīng)用擴(kuò)展運(yùn)算符運(yùn)算符,能寫(xiě)出更精簡(jiǎn)易讀性高的代碼。 1、擴(kuò)展運(yùn)算符簡(jiǎn)介 擴(kuò)展運(yùn)算符( spread )是三個(gè)點(diǎn)(...),可以將一個(gè)數(shù)組轉(zhuǎn)為用逗號(hào)分隔的參數(shù)序列。 說(shuō)的通俗易懂點(diǎn),有點(diǎn)像化骨綿掌,把一個(gè)大元素給打散成一個(gè)個(gè)單獨(dú)的小元素。 showImg(https://segmentfault.c...
摘要:通過(guò)生成器創(chuàng)建的迭代器也是可迭代對(duì)象,因?yàn)樯善髂J(rèn)會(huì)為屬性賦值。我們可以用來(lái)訪問(wèn)對(duì)象的默認(rèn)迭代器,例如對(duì)于一個(gè)數(shù)組獲得了數(shù)組這個(gè)可迭代對(duì)象的默認(rèn)迭代器,并操作它遍歷了數(shù)組中的元素。 ES6 新的數(shù)組方法、集合、for-of 循環(huán)、展開(kāi)運(yùn)算符(...)甚至異步編程都依賴于迭代器(Iterator )實(shí)現(xiàn)。本文會(huì)詳解 ES6 的迭代器與生成器,并進(jìn)一步挖掘可迭代對(duì)象的內(nèi)部原理與使用方法 ...
摘要:起源何為迭代器迭代器是被設(shè)計(jì)專用于迭代的對(duì)象,帶有特定接口。所有的迭代器對(duì)象都擁有方法,會(huì)返回一個(gè)結(jié)果對(duì)象。這個(gè)知名符號(hào)定義了為指定對(duì)象返回迭代器的函數(shù)。接下來(lái)被調(diào)用,迭代器結(jié)果對(duì)象的屬性被讀出并放入了變量。 起源 何為迭代器? 迭代器是被設(shè)計(jì)專用于迭代的對(duì)象,帶有特定接口。所有的迭代器對(duì)象都擁有 next() 方法,會(huì)返回一個(gè)結(jié)果對(duì)象。該結(jié)果對(duì)象有兩個(gè)屬性:對(duì)應(yīng)下一個(gè)值的 value...
閱讀 1373·2019-08-30 15:44
閱讀 2116·2019-08-30 11:04
閱讀 535·2019-08-29 15:17
閱讀 2556·2019-08-26 12:12
閱讀 3146·2019-08-23 18:09
閱讀 932·2019-08-23 15:37
閱讀 1533·2019-08-23 14:43
閱讀 2940·2019-08-23 13:13