ES6的Iterator遍歷器

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方法,都會返回數據結構的當前成員的信息。具體來講,就是返回一個包含valuedone兩個屬性的對象。其中,value屬性是當前成員的值,done屬性是一個布爾值,表示遍歷是否結束。code

ES6 規定,默認的 Iterator 接口部署在數據結構的Symbol.iterator屬性,或者說,一個數據結構只要具備Symbol.iterator屬性,就能夠認爲是「可遍歷的」(iterable)。對象

默認部署了Iterator的數據有blog

-Array索引

-Map

-Set

-String

-TypedArray

-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);
}

 

 

 

總結參考:http://es6.ruanyifeng.com/#docs/iterator

相關文章
相關標籤/搜索