JavaScriptイテレータを学ぶ

JavaScriptイテレータを学ぶ

導入

イテレータは、コンテナ オブジェクトのメモリ割り当ての実装の詳細を気にせずに、リンク リストや配列などのコンテナ オブジェクトを走査できる設計パターンです。簡単に言えば、移動するポインタのようにデータを 1 つずつ取得できるが、終了すると通知されるということです。このようにして、データを取得した後に必要な作業を実行できます。

js のイテレータはどのように見えるか

JavaScript では、イテレータは特別なオブジェクトです。このイテレータ オブジェクトには next() メソッドがあり、各呼び出しはオブジェクト (結果オブジェクト) を返します。結果オブジェクトには 2 つの属性があります。1 つは value で、返される次の値を示します。もう 1 つは done で、ブール値です。シーケンスの最後の値が反復された場合は true になります。イテレータは、現在のコレクション内の値の位置への内部ポインタも保存します。 next() メソッドを呼び出すたびに、以下のオブジェクトの構造と同様に、次に使用可能な値が返されます。

{
  次へ: 関数() {
        戻る {
            価値:''、
            完了: true / false
        }  
    }
}

反復プロトコル

JavaScript 言語の機能が継続的に向上するにつれて、Map、Set、WeakMap などの新しいデータ型がいくつか追加されました。これらのさまざまなデータ構造を統一された方法で反復処理できるようにするために、es6 では反復プロトコルが追加されました。

反復プロトコルは、新しい組み込み実装や構文ではなく、プロトコルです。これらのプロトコルは、特定の規則に従う任意のオブジェクトによって実装できます。

反復プロトコルは、具体的には反復可能プロトコルと反復子プロトコルの 2 つのプロトコルに分けられます。

簡単に言えば、js では、反復プロトコルを満たしている限り、どのオブジェクトでも走査できるということです。

反復可能なプロトコル

反復可能にするには、オブジェクトは@@iteratorメソッドを実装する必要があります。つまり、オブジェクト (またはそのプロトタイプ チェーン内のオブジェクト) には、定数 Symbol.iterator を介してアクセスできるキー @@iterator を持つプロパティが必要です。

簡単に言えば、何かをトラバース可能にしたい場合は、Symbol.iteratorを介してアクセスできる@@iteratorが必要です。

財産

価値

[シンボル.イテレータ]

反復子プロトコルに準拠したオブジェクトを返す引数のない関数。

イテレータプロトコル

イテレータ プロトコルは、有限または無限の値のシーケンスを生成する標準的な方法を定義します。値が有限の場合、すべての値が反復された後にデフォルトの戻り値が返されます。

オブジェクトは、次のセマンティクスを持つnext()メソッドを実装している場合にのみ、イテレータ プロトコルに準拠します。

財産

価値

次の 2 つのプロパティを持つオブジェクトを返す、パラメーターのない関数。

完了 (ブール値)

next() メソッドは、done と value という 2 つのプロパティを持つオブジェクトを返す必要があります。オブジェクト以外の値 (false や undefined など) が返された場合は、例外がスローされます ("iterator.next() がオブジェクト以外の値を返しました")。

反復プロセス

オブジェクトを反復処理する必要がある場合(たとえば、for...of ループに書き込む場合)、まずその @@iterator メソッドがパラメータなしで呼び出され(このときに返される構造は { next: function () { }}です)、次にこのメソッドによって返されるイテレータを使用して反復処理する値を取得します(実際には、この next() メソッドを繰り返し呼び出しているだけです)。

反復の概要

反復プロトコルは次のように要約できます。何かを走査するには、反復可能プロトコルと反復子プロトコルを満たす必要があります。

  • 反復可能プロトコル: このオブジェクトには、Symbol.iterator を通じてアクセスできる @@iterator が必要です。
  • イテレータ プロトコル: これは、next() 関数が value と done (ブール値、最後の要素であるかどうか。done が true の場合、value は省略できます) の 2 つの属性を持つオブジェクトを返すオブジェクトです。

つまり、イテレータ オブジェクトは本質的にポインタ オブジェクトです。ポインターは、ポインター オブジェクトの next() メソッドを通じて移動されます。

カスタム反復

オブジェクトはイテレータを実装していないため、オブジェクトをトラバースすることはできません。オブジェクトのトラバースを実装するには、オブジェクトに前述のイテレータを実装する必要があります。通常、記述方法は 2 つあります。1 つは従来の記述方法で、内部状態を自分で制御する必要があります。もう 1 つは、ジェネレータ関数によって返されるジェネレータのイテレータを使用して実装する方法です。コードは次のとおりです。

伝統的な書き方

obj = {
  名前: 'ジョエル',
  アドレス: 'gz',
  [シンボル.イテレータ]: () => {
     // ここではこれを使用しないでください。これは return fn なので失われます。let index = -1, atrrList = Object.keys(obj);
    定数オブジェクトイテレータ = {
      次へ: () => {
        結果 = ''
        インデックス++
        if (インデックス < atrrList.length) {
          結果 = {
            値: atrrList[インデックス],
            完了: false
          }
        } それ以外 {
          結果 = {
            完了: true
          }
        }
        結果を返す
      }
    }
    objIteratorを返す
  }
}

for (objのconst項目) {
    console.log('atrrs:' + 項目 + ',値:' + obj[項目])
}

ジェネレータ関数の記述

// 反復不可能なオブジェクトの反復子を追加する let obj = {
  a: 1、
  2 倍
}
obj[シンボル.iterator] = 関数* () {
  keys = Object.keys(obj); とします。
  //キー値の長さを取得します。let len ​​= keys.length;
  //ループ変数を定義する let n = 0;
  //条件判定 while (n <= len - 1) {
      生成 { k: keys[n], v: obj[keys[n]] };
      ++ いいえ
  }
}
//返される値はオブジェクトのキーと値です
(let { k, v } of obj) {について
  コンソールにログ出力します。
}

組み込みの反復可能オブジェクト、反復可能オブジェクトの構文、反復可能オブジェクトを受け入れる組み込み API などのその他の関連情報については、ここをクリックしてください。

これで、JavaScript イテレータの学習に関するこの記事は終了です。JavaScript イテレータに関するより関連性の高いコンテンツについては、123WORDPRESS.COM で以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • JavaScript デザインパターン イテレータパターン
  • JavaScriptイテレータの意味と使い方
  • JavaScript デザインパターン イテレータパターン
  • JavaScript 配列反復メソッド
  • Javascript のイテレータと反復インターフェースの詳細な説明

<<:  Linux システムのデュアル ネットワーク カード バインディング構成の実装

>>:  MySQL テーブルデータのインポートとエクスポートの例

推薦する

Dockerコンテナのk8sデプロイメントの実装

環境: (docker、k8s クラスター)、前回 docker で起動した Java プログラムの...

Navicat を使用してリモート Linux MySQL データベースに接続するときに発生する 10061 不明エラーの詳細な説明

Navicat を使用してリモート Linux MySQL データベースに接続すると、不明なエラー ...

HTML の ReadOnly と Enabled の違い

ReadOnly 属性を持つ TextBox は、クライアント上で次のマークアップとして表示されます...

Django プロジェクトを作成して MySQL に接続する方法

1: django-admin.py startproject プロジェクト名2: cd プロジェク...

Vueは小さなフォーム検証機能を実装します

この記事では、フォーム検証を実装するためのVueの具体的なコードを例として紹介します。具体的な内容は...

Zenコーディングリソース更新機能強化

公式サイト: http://code.google.com/p/zen-coding/ Zen コー...

HTML のテキストエリアの改行問題の概要

最近、Textrea に転送したときに、データが本当に行ごとに保存できるかどうかという問題に遭遇しま...

jsはポップアップウィンドウをクリックすることでポップアップログインボックスを実装します

この記事では、ポップアップウィンドウをクリックしたときにポップアップログインボックスを実現するための...

CSSはフロントエンドの画像変形の問題を完璧に解決します

Toutiao IT School で、CSS がフロントエンドの画像変形の問題を完璧に解決するとい...

Win10 インストール Linux システム チュートリアル ダイアグラム

Windows システムに仮想マシンをインストールするには、 VMware Workstationソ...

メタを使用してトラフィックキャッシュをキャンセルし、ページにアクセスするたびにページを更新して簡単にデバッグできるようにします。

コードをコピーコードは次のとおりです。 <!-- ブラウザがローカル キャッシュからページにア...

ウェブデザイン必携ハンドブック 216 ウェブセーフカラー

Web ページ上の色の表現は、さまざまな要因によって影響を受けます。Web ページで非常に美しい配色...

Ansible を使用した Nginx のバッチ デプロイのサンプル コード

1.1 nginxインストールパッケージとインストールスクリプトをクライアントにコピーし、スクリプト...

MySQL で 1000 万件のレコードをすばやくクエリする方法

目次通常のページングクエリ最適化する方法大きなオフセット使用ID制限大量データ問題の最適化通常のペー...

IE6/7 で絶対配置された要素が不可解に消えたりブロックされたりする問題を解決する方法

1. 絶対配置レイヤーの隣接フローティング レイヤーの幅が親レイヤーの幅と等しくなく、フロートがクリ...