摘要:簡單介紹下規范里面迭代器相關的概念。接口指定迭代器對象必須實現一個方法,如下示例偽代碼。方法是否接受參數,在規范中并不嚴格限定,取決于實現當前這個迭代器的對象。表示迭代終結,后續再調用當前迭代器的方法,返回的對象一律為。
簡單介紹下 ES6 規范里面迭代器(Iterator)相關的概念。最近為啥會看到迭代器,是因為看了 fetch 相關的 Headers 接口,為了實現下 Headers 接口就涉及到了迭代器。
迭代器(Iterator)為什么要有迭代器,是為了給不同的數據結構一個統一的迭代方法,不管你是一個 Array 還是一個 Queue 還是一個 Dictionary,反正只要你提供了符合規范的迭代器,程序員就能通過統一的方法來迭代你這個數據結構。迭代器是一個實現了 Iterator 接口的對象。接口指定迭代器對象必須實現一個 next 方法,如下示例偽代碼。
var iterator = { next: function() { // impl } }
next 方法是否接受參數,在規范中并不嚴格限定,取決于實現當前這個迭代器的對象。但是必須能接受無參數的情況,因為 ES6 語法使用迭代器的時候是不會傳參數的,譬如 for-of。next 方法返回的數據結構是 {done:boolean, value:ES6value}。每次調用 next,如果與之關聯的數據結構里面有數據,那么按照當前數據結構自己的規則把當前被迭代到的元素放到返回的數據結構的 value 值中,done 填寫 false。done 標識是否迭代到了最后。當迭代到最后一個元素后,再調用一次 next 后,返回的 done 就應該是 true。用代碼示例下:
function getArrayIterator( array ) { // 等下再說 } 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 }
當迭代器已經迭代完最后一個元素,那么無論調用幾次 next 返回的 done 都是 true。不過規范里面說,如果在迭代的過程中,next 返回的數據結構中沒有 done 這個屬性的話,我們應該視作其值是 false。再來看看 value,其取值可以是規范中的任意類型。當迭代到最后一個元素后,即 done:true 的時候,value 可以是 undefined,也可以被填入一個返回值。MDN 中加了一篇文章的鏈接來說明當 done:true 時候,value 如果被設成有一個 returnValue 的意義,不過我英語比較挫真心沒有看懂,只能列下原文引用:
可迭代對象(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.
迭代器是通過可迭代對象獲得的,譬如數組就是一個可迭代對象。那么如何通過可迭代對象獲得迭代器呢?規范中規定可迭代對象必須實現一個名為 @@iterator 的方法,調用這個方法返回和當前對象掛鉤的迭代器,譬如:
function getArrayIterator( array ) { return array[ "@@iterator" ](); } var iterator = getArrayIterator( [1, 2, 3, 4] );
但是 @@iterator 方法的名字并不是一個 string,而是 Symbol.iterator。Symbol 是ES6 引入的一個新的類型,表示一個獨一無二的值(這里就不展開了)。所以上例獲取迭代器不是正確的寫法,正確的應該是:
function getArrayIterator( array ) { return array[ Symbol.iterator ](); } var iterator = getArrayIterator( [1, 2, 3, 4] );
ES6 中新加了一些針對可迭代對象的語法,譬如 for-of:
var array = [ 1, 2, 3 ]; for ( let i of array ) { console.log( i ); } // 輸出 // 1 // 2 // 3 /* 上面的 for-of 和下面的代碼等價 */ var iterator = array[ Symbol.iterator ](); var iteratorResult = iterator.next(); while( !iteratorResult.done ) { console.log( iteratorResult.value ); iteratorResult = iterator.next(); }迭代器(Iterator)可選屬性
其實迭代器除了規定一定要實現的 next 方法,還有兩個是可選實現的方法 return 和 throw。
returnreturn 方法如果被調用,意味著調用者要終結此次迭代。return 返回一個 {done:true, value:arg} 對象,value 是調用 return 方法時傳入的參數,即:
var iterator = { next: function() { // impl }, return: function( arg ) { return { done: true, value: arg } } }
return 方法被調用后,后續再調用當前迭代器的 next 方法,返回的對象 done 一律為 true。
throwthrow 方法如果被調用,表示迭代的過程中檢測到了異常。一般來說 throw 方法傳入的參數就是錯誤對象(但是這個不是強制規定的)。throw 方法的通常行為應該是以拋出異常的方式拋出傳入的對象,但是這個行為也是建議不強制。如果 throw 方法不拋出異常,那么返回值為 {done:true}。表示迭代終結,后續再調用當前迭代器的 next 方法,返回的對象 done 一律為 true。
因為 return 和 throw 兩個方法是可選實現的,所以在調用迭代器這個兩個方法前,都要檢測這兩個方法是否存在。
補充:
規范里面指出,迭代器也必須是一個可迭代的對象,即:
iterator = { next: function() { }, [Symbol.iterator]: function() { return this; } }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/83100.html
摘要:我們將從概念上理解迭代器是什么,以及在何處使用它們和示例。同時返回一個名為迭代器的對象,這個迭代器將擁有一個名為的方法,該方法將返回一個具有鍵值為和的對象。下圖可以幫助建立可迭代對象迭代器和之間的關系,這種關系稱為迭代協議。 showImg(https://segmentfault.com/img/bVbkk18?w=1000&h=562); 我們將在本文中分析迭代器。迭代器是在Jav...
摘要:更新了個版本,最新正式版是語言的下一代標準,早已在年月正式發布?;静恢С忠苿佣藶g覽器對的支持情況版起便可以支持的新特性。比較通用的工具方案有,,,等。 1、ECMAScript是什么? 和 JavaScript 有著怎樣的關系? 1996 年 11 月,Netscape 創造了javascript并將其提交給了標準化組織 ECMA,次年,ECMA 發布 262 號標準文件(ECMA-...
摘要:擴展運算符簡介擴展運算符是三個點,可以將一個數組轉為用逗號分隔的參數序列。在實際項目中靈活應用擴展運算符運算符,能寫出更精簡易讀性高的代碼。 1、擴展運算符簡介 擴展運算符( spread )是三個點(...),可以將一個數組轉為用逗號分隔的參數序列。 說的通俗易懂點,有點像化骨綿掌,把一個大元素給打散成一個個單獨的小元素。 showImg(https://segmentfault.c...
摘要:通過生成器創建的迭代器也是可迭代對象,因為生成器默認會為屬性賦值。我們可以用來訪問對象的默認迭代器,例如對于一個數組獲得了數組這個可迭代對象的默認迭代器,并操作它遍歷了數組中的元素。 ES6 新的數組方法、集合、for-of 循環、展開運算符(...)甚至異步編程都依賴于迭代器(Iterator )實現。本文會詳解 ES6 的迭代器與生成器,并進一步挖掘可迭代對象的內部原理與使用方法 ...
摘要:起源何為迭代器迭代器是被設計專用于迭代的對象,帶有特定接口。所有的迭代器對象都擁有方法,會返回一個結果對象。這個知名符號定義了為指定對象返回迭代器的函數。接下來被調用,迭代器結果對象的屬性被讀出并放入了變量。 起源 何為迭代器? 迭代器是被設計專用于迭代的對象,帶有特定接口。所有的迭代器對象都擁有 next() 方法,會返回一個結果對象。該結果對象有兩個屬性:對應下一個值的 value...
閱讀 1355·2019-08-30 15:44
閱讀 2099·2019-08-30 11:04
閱讀 518·2019-08-29 15:17
閱讀 2540·2019-08-26 12:12
閱讀 3133·2019-08-23 18:09
閱讀 922·2019-08-23 15:37
閱讀 1522·2019-08-23 14:43
閱讀 2920·2019-08-23 13:13