キーが実行時まで不明で、すべてのキーが同じタイプで、すべての値が同じタイプである場合、オブジェクトにマップを使用します。
個々の要素を操作するロジックがある場合は、オブジェクトを使用します。
オブジェクト上でマップを使用する適用可能な例は何ですか?特に、「実行時までいつキーが不明になるのか?」
var myMap = new Map();
var keyObj = {},
keyFunc = function () { return 'hey'},
keyString = "a string";
// setting the values
myMap.set(keyString, "value associated with 'a string'");
myMap.set(keyObj, "value associated with keyObj");
myMap.set(keyFunc, "value associated with keyFunc");
console.log(myMap.get(keyFunc));
オブジェクト上でマップを使用する適用可能な例は何ですか?
すでに良い例を挙げたと思います。少なくとも、オブジェクト(Functionオブジェクトを含む)をキーとして使用する場合は、Map
sを使用する必要があります。
特に、「実行時までキーが不明になるのはいつですか?」
コンパイル時に不明な場合はいつでも。要するに、 key-valuecollection が必要な場合は、常にMap
を使用する必要があります。コレクションが必要であることを示す良い指標は、コレクションに値を動的に追加および削除する場合、特にそれらの値が事前にわからない場合(たとえば、データベースからの読み取り、ユーザーによる入力など)です。
対照的に、コードの記述中にオブジェクトが持つプロパティの数と数がわかっている場合(形状が静的な場合)は、オブジェクトを使用する必要があります。 @Felixが言ったように: record が必要なとき。必要なのは、フィールドのタイプが異なる場合や、ブラケット表記法を使用する必要がない(またはプロパティ名のセットが限られていることを期待する)場合に役立ちます。
ES2015のMap
では、プレーンオブジェクトを使用する理由は2つだけ残っていると思います。
プロパティの順序が重要でない場合
Promise
-これは将来の値のプロキシです-およびthen
/catch
)それ以外の場合は、プロパティの順序を保持し、プログラム(Map
オブジェクトに割り当てられたすべてのプロパティ)をデータレベル(Map
のすべてのエントリ)から分離するため、Map
自体)。
Map
の欠点は何ですか?
キーが実行時まで不明で、すべてのキーが同じタイプで、すべての値が同じタイプである場合、オブジェクトにマップを使用します。
なぜ誰かがそんなに明らかに間違った何かを書くのか、私にはわかりません。私は言わなければならない、人々は最近MDNでますます間違ったおよび/または疑わしいコンテンツを見つけています。
その文の中に正しいものはありません。マップを使用する主な理由は、オブジェクト値のキーが必要な場合です。値は同じ型でなければならないという考えは、ばかげていますが、もちろんそうかもしれません。実行時までキーが不明な場合、オブジェクトを使用すべきではないという考えは、同様にばかげています。
Map
とObject
の違いの1つは次のとおりです。
Map
は、複雑なデータ型をキーとして使用できます。このような:
const fn = function() {}
const m = new Map([[document.body, 'stackoverflow'], [fn, 'redis']]);
m.get(document.body) // 'stackoverflow'
m.get(fn) //'redis'
watch out:複合データ型の場合、値を取得する場合は、キーと同じ参照を渡す必要があります。
Object
、単純なデータ型(number
、string
)のみをキーとして受け入れます。
const a = {};
a[document.body] = 'stackoverflow';
console.log(a) //{[object HTMLBodyElement]: "stackoverflow"}
この質問はの複製ですが、終了するまで そこからの私の答え です。
他の答えに加えて、Mapsはオブジェクトよりも扱いにくく、操作が難しいことがわかりました。
obj[key] += x
// vs.
map.set(map.get(key) + x)
これは重要です。なぜなら、短いコードは読みやすく、より直接的に表現力があり、より良い プログラマーの頭の中にとどまる 。
別の側面:set()は値ではなくマップを返すため、割り当てを連鎖させることはできません。
foo = obj[key] = x; // Does what you expect
foo = map.set(key, x) // foo !== x; foo === map
マップのデバッグも苦痛です。以下では、マップ内のキーを実際に見ることはできません。そのためにはコードを書く必要があります。
オブジェクトはどのIDEでも評価できます。
Object
sは、キーを値に設定し、それらの値を取得し、キーを削除し、キーに何かが格納されているかどうかを検出できるという点で、Map
sと似ています。このため(および組み込みの代替手段がなかったため)、Object
sはMap
sとして歴史的に使用されてきました。ただし、特定の場合にMap
の使用を推奨する重要な違いがあります。
Object
のキーはString
sおよびSymbol
sですが、関数、オブジェクト、プリミティブなど、Map
の任意の値にできます。Map
のキーは順序付けられますが、オブジェクトに追加されたキーは順序付けられません。したがって、それを反復処理する場合、Map
オブジェクトは挿入順にキーを返します。Map
のサイズは、size
プロパティで簡単に取得できますが、Object
のプロパティの数は手動で決定する必要があります。Map
は反復可能であるため、直接反復することができますが、Object
を反復するには、何らかの方法でキーを取得して反復する必要があります。Object
にはプロトタイプがあるため、マップにデフォルトのキーがあり、注意しないとキーと衝突する可能性があります。 ES5では、map = Object.create(null)
を使用してこれをバイパスできますが、これはめったに行われません。Map
は、キーペアの頻繁な追加と削除を含むシナリオでパフォーマンスが向上する場合があります。