JS表示集合的對象主要有Array、Set、Object、Map,在之前,遍歷它們須要使用2種不一樣的方法,而如今,JS提出了Iterator機制,能夠給不一樣的數據結構提供統一的遍歷方法,就是for…of。換句話說,只有部署了Iterator的數據才能用for…of遍歷。es6
Iterator的遍歷過程是這樣的:數組
(1)建立一個指針對象,指向當前數據結構的起始位置。也就是說,遍歷器對象本質上,就是一個指針對象。數據結構
(2)第一次調用指針對象的next
方法,能夠將指針指向數據結構的第一個成員。spa
(3)第二次調用指針對象的next
方法,指針就指向數據結構的第二個成員。prototype
(4)不斷調用指針對象的next
方法,直到它指向數據結構的結束位置。指針
每一次調用next
方法,都會返回數據結構的當前成員的信息。具體來講,就是返回一個包含value
和done
兩個屬性的對象。其中,value
屬性是當前成員的值,done
屬性是一個布爾值,表示遍歷是否結束。code
ES6 規定,默認的 Iterator 接口部署在數據結構的Symbol.iterator
屬性,或者說,一個數據結構只要具備Symbol.iterator
屬性,就能夠認爲是「可遍歷的」(iterable)。對象
默認部署了Iterator的數據有blog
-Array索引
-Map
-Set
-String
-arguments
-NodeList 對象
一個對象要被for…of遍歷,必須部署Iterator,或者在其原型上部署Iterator,普通對象並無部署Iterator,若是用for…of遍歷,會拋出「not iterable」錯誤
然而,一個相似於數組的普通對象直接調用數組的Symbol.iterator,也是能夠用for…of遍歷的
let iterable = { 0: 'a', 1: 'b', 2: 'c', length: 3, [Symbol.iterator]: Array.prototype[Symbol.iterator] }; for (let item of iterable) { console.log(item); // 'a', 'b', 'c' }
須要注意的是,「相似於數組」這個條件,不單單要以數字爲索引,length屬性也必不可少
兩個條件中,任何一條不知足(就是普通對象),調用數組的Symbol.iterator是行不通的
那麼普通對象到底要怎樣才能被for…of遍歷?
一是利用Object.keys獲得對象的鍵名而後遍歷這個數組
for (var key of Object.keys(someObject)) { console.log(key + ': ' + someObject[key]); }
Iterator的遍歷過程看着像Generator,Generator能夠很簡單就實現Iterator接口,因此第二種方法就是利用Generator方法將對象包裝一下
function* entries(obj) { for (let key of Object.keys(obj)) { yield [key, obj[key]]; } } for (let [key, value] of entries(obj)) { console.log(key, '->', value); }