es6 はオブジェクトをトラバースできますか?

青灯夜游
リリース: 2022-05-19 16:11:08
オリジナル
3622 人が閲覧しました

es6 の「for of」はオブジェクトを横断できません。理由: Iterator インターフェイスは ES6 で導入されました。「for-of」を使用して走査できるのは、Iterator インターフェイスを提供するデータ型のみです。一方、通常のオブジェクトはデフォルトで Iterator インターフェイスを提供しないため、「for-of」は横断。

es6 はオブジェクトをトラバースできますか?

このチュートリアルの動作環境: 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#戻り値なし # にすることもできます##forEach#ループできるのは不可能特定の条件が満たされる場合、少なくとも常にループできます。 Once戻り値なし特定の条件が満たされた場合、ループ続行できます 新しい配列メンバーを形成します。ループできるのは配列のみです。文字列と通常のオブジェクトはループできません。 set 、mapUninterruptible配列メンバーのフィルタリング。ループできるのは配列のみです。文字列と通常のオブジェクトはループできません。設定、マップ中断できません循環可能Array、 object、循環できませんCanループ可能な反復可能オブジェクト、ループ不可能な通常のオブジェクト (統合データ構造トラバーサル)CanJavaScript ビデオ チュートリアル Web フロントエンド ]
ループ本体の length
配列、マップ、セットなど、文字列、通常のオブジェクトはループできない 戻り値なし do...while
Yes while
##Yes戻り値なし ##map
新しい配列を返します。元の配列には影響しません filter
新しい配列を返しますが、元の配列には影響しません for...in
map,set。数値キー名をトラバースでき、プロトタイプ チェーン上のキーも含め、他の手動で追加されたキーもトラバースできます。 戻り値なし for...of
戻り値なし [関連する推奨事項:

以上がes6 はオブジェクトをトラバースできますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
es6
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート