この記事では、ES6 の for ... of ループについて説明します。 古い方法以前は、JavaScript をトラバースする方法が 2 つありました。 まず最初に、古典的な for i ループを紹介します。これを使用すると、配列またはインデックス可能で長さプロパティを持つ任意のオブジェクトを反復処理できます。 for(i=0;i<things.length;i++) { var 物 = 物[i] /* ... */ } 2 番目は for ... in ループで、オブジェクトのキーと値のペアをループするために使用されます。 for(キー in things) { if(!thing.hasOwnProperty(key)) { 続行; } var thing = things[キー] /* ... */ } for ... inループは、オブジェクトの列挙可能なプロパティすべてをループするため、余談と見なされることが多い[1]。これには、プロトタイプ チェーン内の親オブジェクトのプロパティと、メソッドとして割り当てられるプロパティが含まれます。言い換えれば、人々が予想しないようなことが起こります。 for ... in を使用する場合、通常は、不要なプロパティを回避するために、ループ ブロック内に多くのガード句が必要になります。 初期の JavaScript では、この問題をライブラリを通じて解決しました。多くの JavaScript ライブラリ (Prototype.js、jQuery、lodash など) には、each や foreach などのユーティリティ メソッドや関数があり、for i ループや for ... in ループを使用せずにオブジェクトや配列を反復処理できます。 for ... of ループは、サードパーティのライブラリを必要とせずにこれらの問題の一部を解決しようとする ES6 の方法です。 …のfor ... ループ for(const もののもの) { /* ... */ } 反復可能なオブジェクトを反復処理します。 反復可能オブジェクトは、反復プロトコルを実装するオブジェクト、またはジェネレータ関数を返す @@iterator メソッドを定義するオブジェクトです。 この文には理解すべき点がたくさんあります。
これらの質問に一つずつ答えていきましょう。 組み込みの反復可能まず、配列オブジェクトなど、JavaScript の一部の組み込みオブジェクトは、自然に反復可能です。次のコードに示すように、 for ... of ループ内で配列を使用できます。 定数foo = [ 「リンゴ」、「オレンジ」、「ナシ」 ] for(const のもの foo) { console.log(もの) } 出力は配列内のすべての要素です。
配列には、反復可能なオブジェクトを返すエントリ メソッドもあります。この反復可能オブジェクトは、ループを通過するたびにキーと値を返します。たとえば、次のコード: 定数foo = [ 「リンゴ」、「オレンジ」、「ナシ」 ] for(const のもの foo.entries()) { console.log(もの) } 次のように出力されます
エントリ メソッドは、次の構文を使用する場合にさらに便利です。 定数foo = [ 「リンゴ」、「オレンジ」、「ナシ」 ] for(const [キー, 値] of foo.entries()) { console.log(キー,':',値) } for ループでは 2 つの変数が宣言されます。1 つは返される配列の最初の項目 (値のキーまたはインデックス) 用で、もう 1 つは 2 番目の項目 (インデックスが対応する実際の値) 用です。 単純な JavaScript オブジェクトは反復可能ではありません。次のコードを実行すると: // 正常に実行できません const foo = { 「リンゴ」:「オレンジ」, 「梨」:「プルーン」 } for(const [キー, 値] of foo) { console.log(キー,':',値) } エラーが発生します
ただし、グローバル Object オブジェクトの静的エントリ メソッドは、プレーン オブジェクトを引数として受け入れ、反復可能なオブジェクトを返します。次のようなプログラム: 定数foo = { 「リンゴ」:「オレンジ」, 「梨」:「プルーン」 } Object.entries(foo) の const [キー、値] の場合) { console.log(キー,':',値) } 期待通りの出力が得られます:
独自の反復可能オブジェクトを作成する独自の反復可能なオブジェクトを作成する場合は、もう少し時間がかかります。先ほど私が言ったことを覚えているでしょう。
これを理解する最も簡単な方法は、反復可能なオブジェクトを段階的に作成することです。まず、@@iterator メソッドを実装するオブジェクトが必要です。 @@ 表記は少し誤解を招きやすいですが、実際に行っているのは、定義済みの Symbol.iterator シンボルを使用してメソッドを定義することです。 イテレータ メソッドを使用してオブジェクトを定義し、それを反復処理しようとすると、次のようになります。 定数foo = { [シンボル.イテレータ]: 関数() { } } for(const [キー, 値] of foo) { console.log(キー、値) } 新しいエラーが発生しました:
これは、Symbol.iterator メソッドを呼び出そうとしているが、呼び出しの結果がオブジェクトではないことを通知する JavaScript です。 このエラーを解消するには、イテレータ メソッドを使用して、イテレータ プロトコルを実装するオブジェクトを返す必要があります。つまり、イテレータ メソッドは次のキーを持つオブジェクト (関数) を返す必要があります。 定数foo = { [シンボル.イテレータ]: 関数() { 戻る { 次へ: 関数() { } } } } for(const [キー, 値] of foo) { console.log(キー、値) } 上記のコードを実行すると、新しいエラーが発生します。
今回は、JavaScript は Symbol.iterator メソッドを呼び出そうとしたことを通知します。オブジェクトは確かにオブジェクトであり、 next メソッドを実装していますが、 next の戻り値は JavaScript が予期したオブジェクトではありません。 次の関数は、value と done という 2 つのキーを持つ特定の形式のオブジェクトを返す必要があります。 次へ: 関数() { //... 戻る { 完了: false、 値: '次の値' } } 完了キーはオプションです。値が true の場合 (反復子が反復処理を終了したことを示します)、反復処理は終了しています。 done が false または存在しない場合は、値キーが必要です。値キーは、これをループすることによって返される値です。 したがって、最初の 10 個の偶数を返す単純な反復子を含む別のプログラムをコードに追加します。 クラス First20Evens { コンストラクタ() { this.currentValue = 0 } [シンボル.イテレータ]("シンボル.イテレータ") { 戻る { 次へ: (function() { this.currentValue+=2 現在の値が20以上の場合 {done:true} を返す } 戻る { 値:this.currentValue } }).bind(これ) } } } const foo = new First20Evens; for(fooのconst値) { console.log(値) } ジェネレータイテレータ プロトコルを実装するオブジェクトを手動で構築することが唯一の選択肢ではありません。ジェネレーター オブジェクト (ジェネレーター関数によって返される) もイテレータ プロトコルを実装します。上記の例は、ジェネレータを使用して構築すると次のようになります。 クラス First20Evens { コンストラクタ() { this.currentValue = 0 } [シンボル.イテレータ]("シンボル.イテレータ") { 関数*()を返す{ (i=1;i<=10;i++) の場合 { もし(i % 2 === 0) { 利回り i } } }() } } const foo = new First20Evens; for(fooのconst項目) { コンソール.log(アイテム) } この記事ではジェネレーターについて詳しく説明しません。入門書が必要な場合は、この記事をお読みください。今日の重要なポイントは、Symbol.iterator メソッドがジェネレーター オブジェクトを返すようにでき、そのジェネレーター オブジェクトが for ... of ループ内で「そのまま機能する」ということです。 「正常に動作する」とは、ジェネレータが値を生成しなくなるまで、ループがジェネレータの next を呼び出し続けることを意味します。
参考文献 オブジェクトの各列挙可能なプロパティ: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in 要約するES6 ループと反復可能オブジェクトに関するこの記事はこれで終わりです。ES6 ループと反復可能オブジェクトの詳細については、123WORDPRESS.COM で以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: Linux で ping は成功するがポートが利用できない問題を解決する方法
>>: MySQLデータベーステーブルの定期バックアップの実装の詳細な説明
目次1. Dockerをビルドする2. コンテナに入る3. 設定ファイルを変更する4. Kafkaを...
解決 関数 mergeImgs(リスト) { const imgDom = document.cre...
私の MySQL バージョンは MYSQL V5.7.9 です。古いバージョンを使用してください: ...
目次1. 概要1. 原則2. 実装3. スレーブインスタンスを作成する4. マスタースレーブ構成要約...
この記事の例では、Vueドロップダウンメニューのコンポーネント開発の具体的なコードを参考までに共有し...
目次マルチ環境構成とは何ですか? また、なぜそれが必要なのですか? .env ファイルはどこで設定さ...
はじめに: インターフェイス デザイナーの Joshua Porter が自身のブログでこの記事を公...
パスワード入力後にMySQLデータベースがクラッシュする問題と解決策1 ケースの説明最近、基本的な機...
まずは簡単なデータを見てみましょう。 Googleが発表したレポートによると、 ①中国の都市の97%...
目次インストールコンポーネントのインポート基本的な使い方保存したマークダウンまたは HTML テキス...
Docker はプロセスを中核としてシステムリソースを分離する管理ツールです。分離は、オペレーティン...
この記事では、従業員管理登録ページを実装するためのjQueryの具体的なコードを例として紹介します。...
目次1. 数学関数2. 文字列関数3. 日付関数4. 暗号化機能主な MySQL 関数は次のように紹...
MySQL では、同じ列に複数のインデックスを作成できます。意図的であるかどうかにかかわらず、MyS...
Linux での Tomcat の起動とシャットダウンLinux システムでは、コマンド操作を使用し...