キーがすべて文字列であるときにES6マップを使用する点はありますか?


36

プレーンオブジェクトキーは文字列でなければなりませんが、a Mapは任意のタイプのキーを持つことができます。

しかし、私はこれを実際にはほとんど使いません。ほぼすべての場合、とにかく文字列をキーとして使用しています。そして、おそらくnew Map()よりも遅いです{}。それではMap、単純なオブジェクトの代わりにを使用する方が良いかもしれない他の理由はありますか?


3
MDNは、いつものように、良い比較をしています。
クリスヘイズ

1
参考までに、Map は設定と取得の両方で高速に見えます
mpen 16

@mpen – jsperfは現在ダウンしています。あなたは確かによりmap.set('foo', 123)速く実行されていますかobj.foo = 123?それは非常に驚くべきことですので、場合
して、Callum

@callum Uhh..no、正ではありません。いくつかの新しいパフォーマンステストを作成することもできます。
mpen

回答:


42

ランタイムデータ(キャッシュなど)を保存するためにMapプレーンオブジェクト({})よりもsを使用することを好む理由はいくつかあります。

  1. この.sizeプロパティにより、このマップに存在するエントリの数がわかります。
  2. 様々なユーティリティメソッド- .clear().forEach()など。
  3. デフォルトでイテレーターを提供します!

関数の引数を渡す、設定を保存するなど、他のすべてのケースはすべてプレーンオブジェクトを使用して記述されます。

また、覚えておいてくださいコードを早めに最適化しようとしないでください。プロジェクトでパフォーマンスの問題が発生しない限り、プレーンオブジェクトとマップのベンチマークを行うのに時間を無駄にしないでください。


1
Javascriptで使用されるIDハッシュコード関数は何ですか?
パセリエ

1
@Pacerier ===:)
gustavohenke

最近のマップは、プレーンオブジェクトよりもはるかに高速です。
jayarjo

@gustavohenkeそれは真実ではありません。MapSameValueZeroアルゴリズムを使用します。developer.mozilla.org/en-US/docs/Web/JavaScript/...
lolmaus -アンドレイMikhaylov

@ lolmaus-AndreyMikhaylov大丈夫ですが、Mapこれを使ってs について何か言いましたか?
gustavohenke

4

これについてはわかりませんが、パフォーマンスはマップを使用する理由ではないと思います。この更新されたjsperfページをご覧ください。

http://jsperf.com/es6-map-vs-object-properties/73

(少なくとも文字列を処理する場合)オブジェクトは、基本的な設定と取得のためにマップよりもはるかに高速に見えます。


2
それはあなたがパフォーマンステストを書く方法ではありません。
Qix

6
それはあなたが有用なコメントを書く方法ではありません。提案する別の方法論がある場合は、お気軽に詳しく説明してください。具体的には、これらのテストがどのように書かれていたのですか?彼らは何らかの形で無効または役に立たないですか?
-starlogodaniel

9
マイクロベンチマークを介してテストされる言語のセマンティクス/構造は、1つの変数だけが異なる必要があります。テストは反復回数によって異なり、結果の一部は使用されないため、内部ループの内容が最適化されます。一部のテストでは変数を事前宣言しますが、他のテストではforループとインラインで変数宣言を行います-異なるパフォーマンス異常が発生する可能性があります。
Qix

1
痛い、あなたは絶対に正しい。私の防御では、私のバージョンは前のバージョンの改善でしたが、事前宣言と内部ループのコンテンツの両方が最適化されていませんでした。私は私のドラフト大幅に改善同僚と働いていたと私はそれらの問題を解決すると思う:jsperf.com/es6-map-vs-object-properties/88を。ただし、異なるデータ構造に対して異なるループスタイルを使用することは有効だと思います。実際の使用では、人々は最高のパフォーマンスを備えたループ構造を選択し、マップとオブジェクトには異なる「最適な」ループ構造があります。とにかく、キャッチに感謝します。
-starlogodaniel

わかりました。以前はプレーンオブジェクトよりも低速でしたが、最近のブラウザでは大幅に最適化されています。
jayarjo

0

他の回答では、オブジェクトとMapsの最後の違いについて言及していません。

Mapオブジェクトは、キーと値のペアを保持し、キーの元の挿入順序を覚え

したがって、それを反復処理すると、Mapオブジェクトは挿入順にキーを返します。

MDNからの引用、強調鉱山


これが、Map最近のプロジェクトで初めて使用することにした主な理由でした。に表示する必要がある通常のオブジェクトがあり<table>、各プロパティは特定の行に移動します。

let productPropertyOrder = [ "name", "weight", "price", "stocked" ];

let product =
{
    name: "Lasagne",
    weight: "1kg",
    price: 10,
    stocked: true
}

Map目的のキーの順序に従って、オブジェクトをに変換する関数を作成しました。

function objectToMap( obj, order )
{
    let map = new Map();

    for ( const key of order )
    {
        if ( obj.hasOwnProperty( key ) )
        {
            map.set( key, obj[ key ] );
        }
    }

    return map;
}

次に、マップを目的の順序で繰り返します。

let productMap = objectToMap( product, productPropertyOrder );

for ( const value of productMap.values() )
{
    let cell = document.createElement( "td" );
    cell.innerText = value;
    row.appendChild( cell );
}

もちろんMap、プロセス内でを作成せずにプロパティの順序を反復するときに表示することもできるため、これは少し工夫されています。

for ( const key of productPropertyOrder )
{
    if ( product.hasOwnProperty( key ) )
    {
        let value = product[ key ];
        // create cell
    }
}

ただし、そのようなオブジェクトの配列があり、それらを多くの場所に表示する場合は、それらをすべてマップに変換するのがまず理にかなっています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.