es6 の「for of」はオブジェクトを横断できません。理由: Iterator インターフェイスは ES6 で導入されました。「for-of」を使用して走査できるのは、Iterator インターフェイスを提供するデータ型のみです。一方、通常のオブジェクトはデフォルトで Iterator インターフェイスを提供しないため、「for-of」は横断。
このチュートリアルの動作環境: Windows 7 システム、ECMAScript バージョン 6、Dell G3 コンピューター。
フロントエンドの継続的な開発に伴い、for、forEach、do..while、for...in などの多くのライト ループのメソッドが登場しました。ただし、これらのループにも独自のループがあります。アプリケーションシナリオと利点と欠点。
ES6 は、文字列、配列、その他の配列のようなオブジェクトをループできる新しいループ メソッド for...of を提供します。最も一般的な Object オブジェクトであるため、ループできるのは当然です。
以下のコード例を見てみましょう:
{ // 迭代数组 const iterable = ['a', 'b']; for (const value of iterable) { console.log(value); } // output: a b } { // 普通对象 const obj = { a: 'A', b: 'B' } for(const item of obj){ console.log(item) } // Uncaught TypeError: obj is not iterable }
ああ、エラーが報告されました: Uncaught TypeError: obj is not iterable
。ヒント: obj は反復可能ではないため、for...of
を直接使用して Object オブジェクトを走査することはできません。
では、ほとんどのデータ構造を横断できる for...of が Object オブジェクトを横断できないのはなぜでしょうか?
理由:
Iterator は ES6 で導入されました。for-of、while Array のループに使用できるのは、Iterator インターフェイスを提供するデータ型のみです。 Set、Map などのデータ型、および引数などの特定の配列はすべてデフォルトで Iterator インターフェイスを提供するため、for-of を使用して走査できます。
通常のオブジェクトの場合、for...of 構造体を直接使用することはできず、エラーが報告され、obj は反復可能ではありません
というプロンプトが表示されます。これは、通常のオブジェクトが反復可能であることを意味します。デフォルトでは Iterator インターフェイスがありません。Iterator インターフェイスを使用するには、事前に展開する必要があります。
それにどう対処すればよいでしょうか? for-of でオブジェクトを走査しましょう
理由は明らかですが、どうすれば解決できますか?オブジェクトやその他のデータ型に Iterator インターフェイスを提供できますか?
答えは「はい」です。ES6 では Symbol.iterator 属性も提供されます。データ構造にこの属性がある限り、データ構造は、 Iterator インターフェイス。次に、このインターフェイスを実装する方法があります。以下が最も単純な実装です:
newObj[Symbol.iterator] = function(){ let index = 0 , self = this , keys = Object.keys( self ) ; return { next(){ if( index < keys.length ){ return { value: self[keys[index++]] , done: false }; } else{ return { value: undefined , done: true } } } }; };
注意深く見ると、Symbol.iterator インターフェイスが実際には Generator 関数であることがわかります。コードを簡略化します:
newObj[Symbol.iterator] = function* (){ let keys = Object.keys( this ) ; for(let i = 0, l = keys.length; i < l; i++){ yield this[keys[i]]; } } for(let v of newObj){ console.log( v ); } // 输出结果 // 5 // 6
注目に値するのは、Object.keys が for-in が遭遇する継承の問題をたまたま解決する前に
これは私たちの期待を満たしており、for-of を使用してオブジェクトを走査します, しかし、何かが間違っているようです。トラバースします オブジェクトは通常、キーと値を同時に出力することが期待されています。このようにコードを調整すると、
newObj[Symbol.iterator] = function* (){ let keys = Object.keys( this ) ; for(let i = 0, l = keys.length; i < l; i++){ yield { key: keys[i] , value: this[keys[i]] }; } } for(let v of newObj){ console.log( v ); } // 输出结果 // {key: "e", value: 5} // {key: "f", value: 6}
のようにオブジェクトが返されますが、これは非常に不快に思えます。構造化代入を試してみることはできますか? 。 。
for(let {key, value} of newObj){ console.log(key, value ); } // 输出结果 // e 5 // f 6
これは完璧ですね。 。 。
拡張知識: for-of ループと他のループの違い
ループ オブジェクト | ループを中断できるかどうか | 戻り値があるかどうか | |
---|---|---|---|
| forループ本体の length は | #戻り値なし # にすることもできます##forEach | |
配列、マップ、セットなど、文字列、通常のオブジェクトはループできない
| 不可能
戻り値なし |
do...while | |
Yes | 戻り値なしwhile | ||
##Yes 戻り値なし |
##map | 新しい配列メンバーを形成します。ループできるのは配列のみです。文字列と通常のオブジェクトはループできません。 set 、map | |
新しい配列を返します。元の配列には影響しません |
filter | 配列メンバーのフィルタリング。ループできるのは配列のみです。文字列と通常のオブジェクトはループできません。設定、マップ | |
新しい配列を返しますが、元の配列には影響しません |
for...in | 循環可能 | |
map,set。数値キー名をトラバースでき、プロトタイプ チェーン上のキーも含め、他の手動で追加されたキーもトラバースできます。
| Can
戻り値なし
| for...of | ループ可能な反復可能オブジェクト、ループ不可能な通常のオブジェクト (統合データ構造トラバーサル) |
戻り値なし |
[関連する推奨事項: | JavaScript ビデオ チュートリアル、 | Web フロントエンド
以上がes6 はオブジェクトをトラバースできますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。