遍歷器(Iterator)是一種接口,爲各類不一樣的數據結構提供統一的訪問機制。任何數據結構只要部署Iterator接口,就能夠完成遍歷操做(即依次處理該數據結構的全部成員)。es6
Iterator的做用有三個:一是爲各類數據結構,提供一個統一的、簡便的訪問接口;二是使得數據結構的成員可以按某種次序排列;三是ES6有一種新的遍歷方式,for...of,而Iterator的主要做用,就是支持此操做。數組
在ES6中,有些數據結構原生具有Iterator接口(好比數組),即不用任何處理,就能夠被for...of循環遍歷,有些就不行(好比對象)。緣由在於,這些數據結構原生部署了Symbol.iterator屬性(詳見下文),另一些數據結構沒有。數據結構
凡是部署了Symbol.iterator屬性的數據結構,就稱爲部署了遍歷器接口。調用這個接口,就會返回一個遍歷器對象。函數
在ES6中,有三類數據結構原生具有Iterator接口:數組、某些相似數組的對象、Set和Map結構。它們三者不須要咱們手動部署Symbol.iterator屬性就能夠使用for...of遍歷功能。而普通對象使用for...of遍歷就會報錯,由於它沒有部署該接口。spa
若是你須要使本來不具有for...of遍歷功能的集合具有該功能,就須要手動爲它部署。ES6有許多內置的Symbol值,這些就是接口。prototype
下面咱們利用迭代器中的原理來給對象生成一個迭代器,實現讓對象能夠使用for...ofcode
var person={ name: 'zz', age: 18 }
//給person對象添加一個iterator接口
person[Symbol.iterator] = function(){
//使用object.keys()方法把j對象中的k值讀取出來存在數組當中
var arr = Object.keys(person); var i = 0; return { //ES6中next()迭代方法,自動迭代
next(){ if(i < arr.length){ //若是done爲false,繼續迭代
return { //返回迭代的最後結果,若是是一個對象,那麼for of的時候須要用解構
value: { k : arr[i], val: person[arr[i++]] }, done: false } }else{ //若是done爲true,繼續迭代
return { value: null, done : true } } } } }
//解構獲取返回獲得的對象,輸出k值,val值
for(var {key,val} of person){ console.log(key,val); }
咱們能夠看到:對象
一、經過爲person對象部署Symbol.iterator接口,就使它實現了for...of 功能。blog
二、Symbol.iterator中返回一個對象,該對象包含一個next() 方法,定義了遍歷功能。接口
三、next方法中的value和done,value是遍歷過程當中返回的鍵值對信息,done是一個表示遍歷是否結束的布爾值。
補充:
一、遍歷器對象除了具備next方法,還能夠具備return方法和throw方法。若是你本身寫遍歷器對象生成函數,那麼next方法是必須部署的,return方法和throw方法是否部署是可選的。
當一個解構在遍歷的時候異常提早退出(好比break,continue或者出錯)的時候,就會調用return方法,其次,return方法必須返回一個對象。
至於throw方法,則是用於拋出錯誤,Generator.prototype.throw這裏不展開講了,感興趣的能夠搜索一下。
二、用ES6新功能Generator函數來實現Symbol.iterator接口,事半功倍。
var yieldIterator = {}; yieldIterator[Symbol.iterator] = function* () { yield 1; yield 2; yield 3; }; [...yieldIterator] // [1, 2, 3]
注意,yield* 後面跟的是一個可遍歷的結構,它會調用該結構的遍歷器接口。
對Generator不瞭解的能夠戳 ES6 Generator的語法 ,這裏很少說。
三、至於能夠使用Array.from轉換成數組的類數組對象,部署iterator有一種很簡單的方法,即直接使用數組的[Symbol.iterator]接口。
fakeArray.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
一、解構賦值
二、擴展運算符(...)
三、上文提到的 yield*
四、因爲數組的遍歷會調用遍歷器接口,因此任何接受數組做爲參數的場合,都默認調用,如
for...of
Array.from()
Map(), Set(), WeakMap(), WeakSet()
Promise.all()
Promise.race()
五、字符串是一個相似數組的對象,原生也具備Iterator接口