ホームページ  >  記事  >  ウェブフロントエンド  >  ES6イテラブルプロトコルとイテレータプロトコルの詳細説明

ES6イテラブルプロトコルとイテレータプロトコルの詳細説明

小云云
小云云オリジナル
2018-01-15 09:10:071571ブラウズ

この記事では主に ES6 構文の iterable プロトコルと iterator プロトコルを詳しく紹介していますが、編集者が非常に優れていると思ったので、参考として共有します。編集者をフォローして見てみましょう。皆さんのお役に立てれば幸いです。

ECMAScript 2015 へのいくつかの追加は、新しい組み込みや構文ではなく、プロトコルです。これらのプロトコルは、特定の規則に従う任意のオブジェクトによって実装できます。
反復可能プロトコルと反復子プロトコルの 2 つのプロトコルがあります。

反復可能プロトコル

反復可能プロトコルを使用すると、for..of 構造でどのような値を反復 (取得) できるかなど、JavaScript オブジェクトの反復動作を定義またはカスタマイズできます。 Array や Map など、一部の組み込み型は組み込みの反復可能オブジェクトであり、デフォルトの反復動作を持ちますが、そうでない型 (Object など) もあります。

Iterator インターフェースの目的は、すべてのデータ構造に対する統合アクセス メカニズム、つまり for...of ループを提供することです (詳細は以下を参照)。 for...of ループを使用して特定のデータ構造を走査すると、ループは自動的に Iterator インターフェイスを探し、Symbol.iterator メソッドを呼び出し、オブジェクトのデフォルトのイテレータを返します。

ES6 では、デフォルトの Iterator インターフェイスがデータ構造の Symbol.iterator プロパティにデプロイされることが規定されています。つまり、データ構造が Symbol.iterator プロパティを持つ限り、それは「反復可能」であると見なされます。 Symbol.iterator プロパティ自体は関数であり、現在のデータ構造の既定の反復子生成関数です。この関数を実行すると、トラバーサーが返されます。

反復可能なオブジェクトになるためには、オブジェクト (またはそのプロトタイプ チェーン内のオブジェクト) は Symbol.iterator という名前のプロパティを実装する必要があります:

イテレーター プロトコル

イテレーター プロトコルは、有限または無限の値のシーケンス。

「セット」を表すJavaScript本来のデータ構造は主に配列(Array)とオブジェクト(Object)ですが、ES6ではMapとSetが追加されています。このように、4 つのデータ コレクションがあり、ユーザーはそれらを組み合わせて独自のデータ構造を定義することもできます。たとえば、配列のメンバーはマップであり、マップのメンバーはオブジェクトです。これには、すべての異なるデータ構造を処理するための統一されたインターフェイス メカニズムが必要です。

Iterator(イテレーター)はそんな仕組みです。これは、さまざまなデータ構造に統一されたアクセス メカニズムを提供するインターフェイスです。データ構造が Iterator インターフェイスをデプロイしている限り、トラバーサル操作を完了できます (つまり、データ構造のすべてのメンバーを順番に処理します)。

Iterator には 3 つの機能があります。1 つ目は、さまざまなデータ構造に統合されたシンプルなアクセス インターフェイスを提供します。2 つ目は、データ構造のメンバーを特定の順序で配置できるようにします。3 つ目は、ES6 が新しいトラバーサル コマンドを作成します。 ...of ループ、Iterator インターフェイスは主に for...of による消費に使用されます。

Iteratorのトラバース処理はこんな感じです。

  1. 現在のデータ構造の開始位置を指すポインター オブジェクトを作成します。言い換えれば、トラバーサー オブジェクトは本質的にはポインター オブジェクトです。

  2. 初めてポインター オブジェクトの next メソッドを呼び出すときに、ポインターをデータ構造の最初のメンバーに指すことができます。

  3. ポインター オブジェクトの next メソッドが 2 回目に呼び出されるとき、ポインターはデータ構造の 2 番目のメンバーを指します。

  4. データ構造の終わりを指すまで、ポインター オブジェクトの次のメソッドを継続的に呼び出します。

次のメソッドが呼び出されるたびに、データ構造の現在のメンバーの情報が返されます。具体的には、value と Done の 2 つのプロパティを含むオブジェクトを返します。このうち、value 属性は現在のメンバーの値であり、done 属性はトラバーサルが終了したかどうかを示すブール値です。


var someString = "hi";
typeof someString[Symbol.iterator]; // "function"
var iterator = someString[Symbol.iterator]();
iterator + "";  // "[object String Iterator]"
iterator.next()    // { value: "h", done: false }
iterator.next();   // { value: "i", done: false }
iterator.next();   // { value: undefined, done: true }

Iteratorインターフェースを備えたネイティブデータ構造は次のとおりです。

  1. Array

  2. Map

  3. Set

  4. String

  5. TypedArray

  6. 関数引数オブジェクト

  7. NodeList オブジェクト

オブジェクトにはIterator インターフェイス はい、オブジェクトが for...of ループで呼び出すことができる Iterator インターフェイスを持ちたい場合は、Symbol.iterator のプロパティにトラバーサー生成メソッドをデプロイする必要があります (プロトタイプ チェーン上のオブジェクトは、この方法)。

Iterator インターフェイスを呼び出す場合

以下で紹介する for...of ループに加えて、Iterator インターフェイス (つまり、Symbol.iterator メソッド) がデフォルトで呼び出される場合があります。また、スプレッド演算子は、デフォルトの Iterator インターフェイスとも呼ばれます。

実際、これは、Iterator インターフェイスでデプロイされたデータ構造を配列に変換する簡単なメカニズムを提供します。つまり、データ構造が Iterator インターフェイスをデプロイしている限り、スプレッド演算子を使用して配列に変換できます。

配列トラバーサルはトラバーサー インターフェイスを呼び出すため、配列をパラメーターとして受け入れる場合は実際にトラバーサー インターフェイスを呼び出します。ここではいくつかの例を示します。

  1. for...of

  2. Array.from()

  3. Map()、Set()、WeakMap()、WeakSet() (new Map([['a',1など) ] ,['b',2]]))

  4. Promise.all()

  5. Promise.race()

for...of

for...of 循环是最新添加到 JavaScript 循环系列中的循环。

它结合了其兄弟循环形式 for 循环和 for...in 循环的优势,可以循环任何可迭代(也就是遵守可迭代协议)类型的数据。默认情况下,包含以下数据类型:String、Array、Map 和 Set,注意不包含 Object 数据类型(即 {})。默认情况下,对象不可迭代。

在研究 for...of 循环之前,先快速了解下其他 for 循环,看看它们有哪些不足之处。

for 循环

for 循环的最大缺点是需要跟踪计数器和退出条件。我们使用变量 i 作为计数器来跟踪循环并访问数组中的值。我们还使用 Array.length 来判断循环的退出条件。

虽然 for 循环在循环数组时的确具有优势,但是某些数据结构不是数组,因此并非始终适合使用 loop 循环。

for...in 循环

for...in 循环改善了 for 循环的不足之处,它消除了计数器逻辑和退出条件。但是依然需要使用 index 来访问数组的值.

此外,当你需要向数组中添加额外的方法(或另一个对象)时,for...in 循环会带来很大的麻烦。因为 for...in 循环循环访问所有可枚举的属性,意味着如果向数组的原型中添加任何其他属性,这些属性也会出现在循环中。这就是为何在循环访问数组时,不建议使用 for...in 循环。

注意: forEach 循环 是另一种形式的 JavaScript 循环。但是,forEach() 实际上是数组方法,因此只能用在数组中。也无法停止或退出 forEach 循环。如果希望你的循环中出现这种行为,则需要使用基本的 for 循环。

for...of 循环

for...of 循环用于循环访问任何可迭代的数据类型。


const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

for (const digit of digits) {
 console.log(digit);
}

可以随时停止或退出 for...of 循环。


const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

for (const digit of digits) {
 if (digit % 2 === 0) {
  continue;
 }
 console.log(digit); //1,3,5,7,9
}

不用担心向对象中添加新的属性。for...of 循环将只循环访问对象中的值。

相关推荐:

实例分享PHP迭代器接口Iterator用法分析

调整JavaScript抽象的迭代方案

JavaScript数组的5种迭代方法实例详解


以上がES6イテラブルプロトコルとイテレータプロトコルの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。