JavaScript Map でキーと値を順序付き管理
JavaScript の Map オブジェクトはキーと値のペアを保存し、キーにオブジェクト、関数、プリミティブなど任意の値を使えます。挿入順で反復したいとき、文字列以外のキーが必要なとき、追加と削除が多いときに使います。プレーンオブジェクトと違って、Map のキーは継承されたプロトタイププロパティの影響を受けないため、動的な文字列キーでも意図しない衝突を避けられます。
キーと値を保存する JavaScript Map の例
出力:
ここに出力が表示されます...
出力:
95
false
2
この例の仕組み
new Map()は空の map を作成します。newを付けずにMap()を呼ぶとTypeErrorが発生します。setはキーと値のペアを追加し、Mapインスタンス自身を返します。これによりmap.set("a", 1).set("b", 2)のようにチェーンできます。既存キーにsetすると、反復位置を変えずに値だけ上書きします。getは保存された値を返し、キーが存在しない場合はundefinedを返します。undefinedが値として設定されている場合と未登録キーを区別するにはhasを使います。sizeは現在のエントリ数を返します。オブジェクトのようにObject.keys(obj).lengthを使う必要はありません。
JavaScript Map でよくある間違い
set/get ではなくブラケット記法を使う:
悪い例:
const map = new Map();
map["キー"] = "値";
console.log(map.get("キー")); // undefined
正しい例:
const map = new Map();
map.set("キー", "値");
console.log(map.get("キー")); // "値"
ブラケット記法は Map エントリではなく、Map インスタンス上のオブジェクトプロパティを設定します。get、has、size はそれを参照しません。
オブジェクトキーが構造で等価比較されると考える:
悪い例:
const map = new Map();
map.set({id: 1}, "太郎");
console.log(map.get({id: 1})); // undefined
正しい例:
const key = {id: 1};
map.set(key, "太郎");
console.log(map.get(key)); // "太郎"
Map はキーの等価性に SameValueZero を使います。オブジェクトでは参照同一性で比較されるため、見た目が同じオブジェクトリテラルでも別キーとして扱われます。
JavaScript Map vs Object
Map | Object | |
|---|---|---|
| キーの型 | 任意の値(オブジェクト、関数、プリミティブ) | 文字列と Symbol のみ |
| 反復順序 | 挿入順(保証される) | ほぼ挿入順だが、整数風キーは先に並ぶ |
| サイズ | map.size | Object.keys(obj).length |
| プロトタイプ衝突 | なし | toString、constructor などと衝突する可能性がある |
| JSON シリアライズ | Object.fromEntries で手動変換 | JSON.stringify をそのまま使える |
キーが文字列以外のとき、エントリの追加と削除が多いとき、信頼できないキーを扱うときは Map を使います。固定形のレコードや JSON 化が必要なデータにはプレーンオブジェクトを使います。
オブジェクトを使いたいがプロトタイプキー衝突を避けたい場合は、Object.create(null) を基盤オブジェクトにします。
FAQ
JavaScript Map は挿入順を保持しますか?
はい。Map はエントリを最初に挿入した順で反復します。既存キーに set() した場合は値だけ更新され、元の位置は維持されます。キーを削除して再追加すると末尾へ移動します。
JavaScript Map でオブジェクトをキーにできますか?
はい。ただし Map はオブジェクトキーを構造ではなく参照で比較します。同じプロパティを持つ別オブジェクトは別キーです。変数に参照を保存し、その同じ参照を set と get の両方で使ってください。
JavaScript Map をオブジェクトや JSON に変換するには?
Object.fromEntries(map) を呼ぶとプレーンオブジェクトを作成できます。ただし有効なのは、すべてのキーが文字列または Symbol の場合です。文字列以外のキーがある場合は、エントリ配列を JSON.stringify([...map]) でシリアライズします。
JavaScript Map と JavaScript の map() 関数の違いは?
Map はデータを保存・検索するためのキーと値のコレクションです。JavaScript の map() 関数(Array.prototype.map)は、各要素にコールバックを適用して新しい配列を返す配列メソッドです。名前は同じですが用途は異なります。