1. 程式人生 > 實用技巧 >Symbol.iterator和Symbol.asyncIterator

Symbol.iterator和Symbol.asyncIterator

Symbol.iterator和Symbol.asyncIterator

Symbol.iterator

Symbol.iterator為每一個物件定義了預設的迭代器。該迭代器可以被for...of迴圈使用。

當需要對一個物件進行迭代時(比如開始用於一個for...of迴圈中),它的@@iterator方法都會在不傳參情況下被呼叫,返回的迭代器用於獲取要迭代的值。

一些內建型別擁有預設的迭代器行為,其他型別(如Object)則沒有。下表中的內建型別擁有預設的@@iterator方法:

  • Array.prototype[@@iterator]()
  • TypedArray.prototype[@@iterator]()
  • String.prototype[@@iterator]()
  • Map.prototype[@@iterator]()
  • Set.prototype[@@iterator]()

示例

自定義迭代器

我們可以像下面這樣建立自定義的迭代器:

/** 自定義迭代器 */
var myIterable = {};
myIterable[Symbol.iterator] = function* () {
    yield 1;
    yield 2;
    yield 3;
}

console.log([...myIterable])

不符合標準的迭代器

如果一個迭代器@@iterator沒有返回一個迭代器物件,那麼它就是一個不符合標準的迭代器,這樣的迭代器將會在執行期丟擲異常,甚至非常詭異的Bug

Symbol.asyncIterator

Symbol.asyncIterator符號指定了一個物件的預設非同步迭代器。如果一個物件設定了這個屬性,它就是非同步迭代物件,可用於for await...of迴圈

Symbol.asyncIterator是一個用於訪問物件的@@asyncIterator方法的內建符號。一個非同步可迭代物件必須要有Symbol.asyncIterator屬性

示例

自定義非同步可迭代物件

/** 自定義非同步可迭代物件 */
const myAsyncIterable = new Object();
myAsyncIterable[Symbol.asyncIterator] 
= async function*() { yield "hello"; yield "async"; yield "iteration!"; } (async () => { for await (const x of myAsyncIterable) { console.log(x); } })();

內建非同步可迭代物件

目前沒有預設設定了[Symbol.asyncItetor]屬性的JavaScript內建的物件。不過,WHATWG(網頁超文字應用技術工作小組)Streams會被設定為第一批非同步可迭代物件,[Symbol.asyncItertor]最近已在設計規範中落地。