Javascript ES6 Iterators建議指南(含實例)

由Arfat Salman發佈

本文旨在分析理解 Iterators 。 Iterators 是 JavaScript 中的新方法,能夠用來循環任意集合。在ES6中登場的Iterators。因其可被普遍使用,而且已在多處場景派上用場,現已十分流行。html

咱們從概念上去理解iterators,經過實例講述在何處使用。而且. We’ll also see some of its implementations in JavaScript.node

介紹

若是你有下面的數組 ——es6

const myFavouriteAuthors = [
  'Neal Stephenson',
  'Arthur Clarke',
  'Isaac Asimov', 
  'Robert Heinlein'
];

有時,你須要獲取這個數組中每個值,在屏幕上顯示它們,操做它們,或者依據它們作些事情。若是我問你將如何處理?你會說,這很簡單——我循環它們就是了,能夠用for__, while__, for-of 或者 這些 循環方法中的任意一個。web

各類循環數組的方法

若是如今不是前面的數組,而是以自定的數據結構保存全部的authors,好比——數組

自定數據結構

如今, myFavouriteAuthors 是一個包含了對象 allAuthors 的對象, allAuthors 包含了三個數組,對應key值爲 fiction , scienceFiction ,和 fantasy 。 如今若是須要遍歷 myFavouriteAuthors 來獲取全部的做者, 你的方法是什麼? 你能夠繼續嘗試一些循環組合來獲取全部數據。瀏覽器

然而,若是你這樣作 —數據結構

for (let author of myFavouriteAuthors) {   
console.log(author)
}

// TypeError: {} is not iterable</pre>

你會獲得一個該對象不是_可迭代的_TypeError。 咱們來看看迭代是什麼,以及咱們如何使對象可迭代。 在本文的最後,你將知道如何在這種狀況下,在 myFavouriteAuthors 上,在自定義對象上使用 for-of 循環。ide

Iterables(可迭代對象) and Iterators(迭代器)

在上一節中看到了問題所在。 沒有方法能夠簡單得從咱們的自定義對象中獲取全部做者。 咱們想要一種方法,經過它咱們能夠有序地呈現全部內部數據。函數

讓咱們在 myFavouriteAuthors 中添加一個返回全部做者的方法 getAllAuthors 。 像這樣 ——oop

getAllAuthors 的實現

這是一個簡單的方法。 它完成了得到全部做者的當下目標。 可是,這種實現可能會出現一些問題。 好比——

  • getAllAuthors 這個名字很是具體。 若是其餘人正在建立他們本身的 myFavouriteAuthors ,他們可能會將其命名爲 retrieveAllAuthors 。
  • 做爲開發人員,咱們始終須要了解將返回全部數據的特定方法。 在這個案例裏,它被命名爲 getAllAuthors 。
  • getAllAuthors 返回包含全部做者的字符串數組。 若是另外一個開發人員以這種格式返回一個對象數組會怎樣——

[ {name: 'Agatha Christie'}, {name: 'J. K. Rowling'}, ... ]</pre>

開發人員必須知道,返回全部數據的方法的 確切名稱和返回類型 。

若是咱們制定一個 規則 ,該方法的 名稱 及其 返回類型 , 是固定且不可更改的 ,這怎麼辦?

讓咱們將這個方法命名爲—— iteratorMethod .

ECMA 採起了相似的步驟,來標準化循環自定義對象的過程。可是,ECMA使用 Symbol.iterator 而不是 iteratorMethod 。 Symbols 提供惟一且不能與其餘屬性名稱衝突的名稱。 此外, Symbol.iterator 將返回一個名爲 iterator 的對象。 這個迭代器將有一個名爲 next 的方法,它將返回一個包含key爲 value 和 done 對象,

key value 中將包含當前值。 它能夠是任何類型。 done 是布爾值。 它表示是否已獲取全部值。

下圖可能有助於創建  iterables  ,  iterators  和  next  之間的關係。 這種關係稱爲迭代協議。

![iterables, iterators, 和 next之間的關係。
](http://upload-images.jianshu....

參考 Axel Rauschmayer博士 的 Exploring JS 一書 —

  • _ iterable _是一種數據結構,旨在使其元素可在公用環境被訪問。 它經過實現一個key爲 Symbol.iterator 的方法來實現。 該方法是 iterators 的工廠。 也就是說,它將建立 iterators **.
  • iterator 是用於遍歷數據結構中元素的指針。

使對象可迭代

正如咱們在上一節中所學到的,咱們須要實現一個名爲 Symbol.iterator 的方法。咱們將使用 computed property syntax 來設置這個key。舉一個簡短的例子 —

可迭代的示例

在第4行,咱們建立iterator。 這是一個定義了 next 方法的對象。 next 方法根據 step 變量返回對應的值。 在第25行,咱們取到 iterator 。 27行,咱們調用 next 方法。 接下來咱們繼續調用,直到 done 變成'true`。

這正是 for-of 循環中發生的事情。 for-of 循環採用 iterable ,併爲其建立  iterator 。 不斷調用 next() 直到 done 爲真。

JavaScript中的 Iterables

不少東西在JavaScript中都是可迭代的。 它可能不是立等可見的,但若是仔細觀察,是能看到iterables的。

這些都是可迭代的 ——

  • Arraysand TypedArrays
  • Strings —迭代每一個字符或 Unicode code-points.
  • Maps —迭代 key-value 組合
  • Sets —迭代它們的元素
  • arguments — 函數中一個相似數組的特殊變量
  • DOM 元素 (實現中)

其餘在JS中使用iterables的 ——

  • for-of 循環 — for-of 循環須要迭代。 不然,它將拋出一個 TypeError .
for (const value of iterable) { ... }</pre>
  • 數組的解構 ——因爲可迭代而發生解構。 咱們來看看如何實現。

代碼:

const array = ['a', 'b', 'c', 'd', 'e'];
const [first, ,third, ,last] = array;</pre>

至關於

const array = ['a', 'b', 'c', 'd', 'e'];

const iterator = array[Symbol.iterator]();

const first = iterator.next().value
iterator.next().value // Since it was skipped, so it's not assigned
const third = iterator.next().value
iterator.next().value // Since it was skipped, so it's not assigned
const last = iterator.next().value</pre>
  • 延展符 (…)

代碼:

const array = ['a', 'b', 'c', 'd', 'e'];

const newArray = [1, ...array, 2, 3];</pre>

能夠寫成

const array = ['a', 'b', 'c', 'd', 'e'];

const iterator = array[Symbol.iterator]();

const newArray = [1];
for (let nextValue = iterator.next();nextValue.done !== true;nextValue = iterator.next()) {  
newArray.push(nextValue.value);
}

newArray.push(2)
newArray.push(3)
  • Promise.all 和 Promise.race 接受Promises上的迭代。
  • Maps and Sets

Map的構造函數將 [key,value] 形式的迭代器轉換爲Map,Set的構造函數將可迭代的元素轉換爲Set——

const map = new Map([[1, 'one'], [2, 'two']]);
map.get(1) 
// one
const set = new Set(['a', 'b', 'c]);
set.has('c');
// true
  • 要理解generator 函數,先理解迭代器。

讓myFavouriteAuthors可迭代

這是一個使myFavouriteAuthors可迭代的實現方式。

可迭代的實現示例

根據本文的介紹,您能夠輕鬆瞭解迭代器的工做方式。 可能有點難以理解它的邏輯,因此,我已經爲代碼寫了註釋。 可是,吸取和理解概念的最佳方法是讓這些代碼在瀏覽器或node中運行起來。

若有疑問,歡迎回復! 參考:

原文連接:https://www.jianshu.com/p/58b...

相關文章
相關標籤/搜索