es6 Iterator遍歷器

suydCao發表於2018-12-05

1.什麼是Iterator

遍歷器(Iterator)它是一種介面,為各種不同的資料結構提供統一的訪問機制。任何資料結構只要部署 Iterator介面,就可以完成遍歷操作(即依次處理該資料結構的所有成員)。

2.Iterator的作用

Iterator 的作用有三個:一是為各種資料結構,提供一個統一的、簡便的訪問介面;二是使得資料結構的成員能夠按某種次序排列;三是ES6創造了一種新的遍歷命令for...of迴圈,Iterator 介面主要供for...of消費。

3.過程

(1)建立一個指標物件,指向當前資料結構的起始位置。也就是說,遍歷器物件本質上,就是一個指標物件。

(2)第一次呼叫指標物件的next方法,可以將指標指向資料結構的第一個成員。

(3)第二次呼叫指標物件的next方法,指標就指向資料結構的第二個成員。

(4)不斷呼叫指標物件的next方法,直到它指向資料結構的結束位置。


var it = makeIterator(['a', 'b']);

it.next() // { value: "a", done: false }
it.next() // { value: "b", done: false }
it.next() // { value: undefined, done: true }

function makeIterator(array) {
  var nextIndex = 0;
  return {
    next: function() {
      return nextIndex < array.length ?
        {value: array[nextIndex++], done: false} :
        {value: undefined, done: true};
    }
  };
}
/*
每一次呼叫next方法,都會返回資料結構的當前成員的資訊。
具體來說,就是返回一個包含value和done兩個屬性的物件。
其中,value屬性是當前成員的值,done屬性是一個布林值,表示遍歷是否結束。
*/
複製程式碼

4.預設 Iterator 介面

一個資料結構只要具有Symbol.iterator屬性,就可以認為是可遍歷的。

const obj = {
  // Symbol是es6裡一個特殊的型別,所以放在[]裡。
  [Symbol.iterator] : function () { // Symbol.iterator是一個方法
    return { // 返回一個遍歷器物件
      next: function () { // 遍歷器物件具有next方法
        return { // 返回包含當前成員的物件
          value: 1,
          done: true
        };
      }
    };
  }
};

複製程式碼

原生具備Iterator介面的資料型別有Array,Map,Set,String,TypedArray,函式的 arguments 物件,NodeList 物件。

物件(Object)之所以沒有預設部署 Iterator 介面,是因為物件的哪個屬性先遍歷,哪個屬性後遍歷是不確定的,需要開發者手動指定。

// 類陣列物件要具有iterator介面,簡單的辦法是
NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
// 或者
NodeList.prototype[Symbol.iterator] = [][Symbol.iterator];
複製程式碼

5.使用的場合

for ... of ...

陣列的結構賦值

展開運算子 '...'

yield*

...

6.Iterator 介面與 Generator 函式

let myIterable = {
  [Symbol.iterator]: function* () {
    yield 1;
    yield 2;
    yield 3;
  }
}
[...myIterable] // [1, 2, 3]

// 或者採用下面的簡潔寫法

let obj = {
  * [Symbol.iterator]() {
    yield 'hello';
    yield 'world';
  }
};

for (let x of obj) {
  console.log(x);
}
// "hello"
// "world"
複製程式碼

7.return()方法

return方法的使用場合是,如果for...of有迴圈出錯,或者有break語句,就會呼叫return方法。如果一個物件在完成遍歷前,需要清理或釋放資源,就可以部署return方法。

相關文章