現代のJavaScript開発において、データをキーと値のペアで管理する「辞書(Dictionary)」の構造は、あらゆるアプリケーションの基盤となります。
JavaScriptには、伝統的に辞書として使われてきたObjectと、辞書専用の機能を持つMapという2つの主要な選択肢が存在します。
これらを適切に使い分けることは、コードの可読性だけでなく、実行パフォーマンスやメモリ効率を最適化する上でも極めて重要です。
本記事では、実務で役立つ具体的な操作方法から、2026年現在の開発環境に即した使い分けの基準まで、詳しく解説します。
JavaScriptにおける辞書データの基本概念
JavaScriptで「辞書」という言葉を使う場合、一般的には「連想配列」や「ハッシュマップ」と同じ概念を指します。
特定のキーを指定することで、それに対応する値に瞬時にアクセスできるデータ構造が辞書の特徴です。
JavaScriptには辞書という名前のデータ型は直接存在しませんが、標準のObject(オブジェクト)と、ES2015で導入されたMap(マップ)がその役割を果たします。
古くからの開発ではObjectが主流でしたが、複雑なデータ構造や動的なキー操作が必要な場面では、現在ではMapの利用が推奨されるケースが増えています。
Objectを利用した辞書の基本操作
JavaScriptのオブジェクトは、最もシンプルに辞書を表現できる方法です。
中括弧{}を使って直感的に定義でき、データの読み書きも非常に容易です。
オブジェクトの定義とデータの読み書き
オブジェクトを辞書として使う場合、リテラル構文を用いてキーと値を定義します。
// オブジェクトによる辞書の作成
const userDictionary = {
id_101: "田中 太郎",
id_102: "佐藤 花子",
id_103: "鈴木 一郎"
};
// 値の取得(ドット記法またはブラケット記法)
console.log(userDictionary.id_101);
console.log(userDictionary["id_102"]);
// 値の追加・更新
userDictionary.id_104 = "高橋 次郎";
田中 太郎
佐藤 花子
オブジェクトのキーは、内部的に文字列またはSymbol(シンボル)として扱われます。
数値をキーとして指定した場合でも、自動的に文字列に変換される点に注意が必要です。
Object.keys, values, entriesによる反復処理
辞書内のデータを一括して処理したい場合は、Objectクラスの静的メソッドを使用します。
const scores = { math: 80, english: 90, science: 75 };
// キーの一覧を取得してループ
Object.keys(scores).forEach(key => {
console.log(`教科: ${key}`);
});
// キーと値のペア(エントリ)を取得してループ
for (const [key, value] of Object.entries(scores)) {
console.log(`${key}の点数は${value}点です。`);
}
教科: math
教科: english
教科: science
mathの点数は80点です。
englishの点数は90点です。
scienceの点数は75点です。
Mapオブジェクトによる高度な辞書管理
Mapは、キーと値のペアを保持するために設計された、より純粋な辞書データ構造です。
Objectとは異なり、任意の型の値をキーとして使用できる点が最大の特徴です。
Mapの基本的な使い方
Mapを生成するには、new Map()コンストラクタを使用します。
// Mapの初期化
const productMap = new Map([
["p001", "ノートPC"],
["p002", "マウス"]
]);
// データの追加(set)
productMap.set("p003", "キーボード");
// データの取得(get)
console.log(productMap.get("p001"));
// 存在確認(has)
console.log(productMap.has("p002"));
// サイズの取得
console.log(productMap.size);
ノートPC
true
3
Mapではsizeプロパティによって、要素数を定数時間で取得できるのが便利です。
Objectの場合、要素数を知るにはObject.keys(obj).lengthを実行する必要があり、要素数に比例した処理時間がかかるため、Mapの方が効率的です。
オブジェクトや関数をキーにする利点
Mapでは、文字列以外のデータ型、例えば別のオブジェクト自体をキーにすることが可能です。
const userKey = { id: 1 };
const sessionMap = new Map();
// オブジェクトをキーとしてセット
sessionMap.set(userKey, { lastLogin: "2026-05-20" });
console.log(sessionMap.get(userKey));
{ lastLogin: "2026-05-20" }
これにより、メタデータを管理する際に、元のデータ自体を識別子として直接紐づけることができます。
ObjectとMapの徹底比較と使い分けの基準
どちらを使うべきか迷った際は、以下の比較表を参考にしてください。
| 特徴 | Object | Map |
|---|---|---|
| キーの種類 | String, Symbolのみ | あらゆる型(Object, Function等も可) |
| 要素の順序 | 基本的には挿入順だが例外あり | 厳密に挿入順を保持 |
| 要素数の取得 | 手動での計算が必要 | sizeプロパティで取得可 |
| 反復処理 | Object.entries等が必要 | iterableであり、直接for…of可 |
| JSON変換 | 標準で対応(JSON.stringify) | 工夫が必要 |
| パフォーマンス | 静的な定義に強い | 頻繁な追加・削除に強い |
Objectを選択すべきシーン
あらかじめキーが決まっている静的なデータ構造や、単純な設定ファイルの管理にはObjectが適しています。
また、APIとの通信でJSON形式を扱う場合は、Objectが標準であるため、そのまま利用するのが自然です。
ライブラリを介さずにシンプルなロジックを記述したい場合、リテラル表記が使えるObjectは記述量が少なく済みます。
Mapを選択すべきシーン
実行時にキーが動的に増減する場合や、キーの種類が事前に予測できない場合は、Mapの方がパフォーマンスに優れます。
特に大規模なデータセットを扱う場合や、データの追加・削除が頻繁に行われるループ内では、Mapの方がメモリ効率が良い傾向にあります。
また、要素の挿入順序が重要なロジック(キャッシュの管理など)では、順序が保証されているMapが必須となります。
実務で役立つ辞書操作のテクニック
ここでは、実務のコードで頻出する、辞書データを効率的に操作するテクニックを紹介します。
デフォルト値の設定(Null合体演算子の活用)
辞書から値を取得する際、キーが存在しない場合にデフォルト値を設定するパターンは非常に多いです。
const config = { theme: "dark" };
// キーがない場合は "light" を使う
const currentTheme = config.theme ?? "light";
console.log(currentTheme);
dark
Object.groupByによるデータのグループ化
2024年以降、JavaScriptの標準機能として組み込まれたObject.groupByは、配列を辞書形式に変換する際に極めて強力です。
const inventory = [
{ name: "りんご", type: "fruit" },
{ name: "キャベツ", type: "vegetable" },
{ name: "バナナ", type: "fruit" }
];
// カテゴリごとにグループ化
const grouped = Object.groupBy(inventory, ({ type }) => type);
console.log(grouped);
{
fruit: [ { name: "りんご", ... }, { name: "バナナ", ... } ],
vegetable: [ { name: "キャベツ", ... } ]
}
以前はreduceメソッドを使って複雑なコードを書く必要がありましたが、このメソッドにより非常に簡潔に辞書化が可能になりました。
辞書のクローンとマージ
既存の辞書を壊さずに新しい情報を追加したり、複数の辞書を統合したりする場合は、スプレッド構文を活用します。
const baseSettings = { color: "blue", fontSize: 14 };
const userSettings = { fontSize: 18, bold: true };
// 2つのオブジェクトをマージ(後のものが優先される)
const finalSettings = { ...baseSettings, ...userSettings };
console.log(finalSettings);
{ color: "blue", fontSize: 18, bold: true }
Mapの場合は、コンストラクタに配列を展開して渡すことで同様のマージが可能です。
パフォーマンスとメモリ管理の最適化
辞書を扱う際、特に長期間動作するアプリケーションでは、メモリリークへの配慮が必要です。
プロトタイプ汚染への対策
Objectを辞書として使う場合、Object.prototypeからの継承が予期せぬ挙動を引き起こすことがあります。
例えば、"toString"というキーが辞書に含まれているかどうかをチェックすると、意図せず真(true)を返してしまうことがあります。
これを防ぐには、Object.create(null)を使用して、プロトタイプを持たない純粋な辞書オブジェクトを作成するのが安全です。
const safeDict = Object.create(null);
console.log(safeDict.toString); // undefined となり、安全
WeakMapによるメモリ管理
キーとなるオブジェクトが参照されなくなった際に、自動的にメモリから解放されるようにしたい場合は、WeakMapを使用します。
WeakMapは、キーとしてオブジェクトのみを指定でき、そのキーへの参照が他に存在しなくなった場合にガベージコレクションの対象となります。
プライベートデータの保持や、DOM要素に関連付けたデータ管理に最適です。
辞書のシリアライズにおける注意点
MapをJSON形式に変換しようとすると、期待通りの結果が得られないという落とし穴があります。
JSON.stringifyは、Mapオブジェクトを単なる空のオブジェクト{}として変換してしまいます。
const myMap = new Map([["key", "value"]]);
console.log(JSON.stringify(myMap));
{}
MapをJSONとして保存したい場合は、一度配列やオブジェクトに変換する必要があります。
// Mapをオブジェクトに変換してからシリアライズ
const objFromMap = Object.fromEntries(myMap);
const jsonString = JSON.stringify(objFromMap);
まとめ
JavaScriptにおける辞書操作は、開発の規模や要件に応じてObjectとMapを賢く使い分けることが成功の鍵です。
単純なデータ構造やJSONとの親和性を重視する場合はObjectを選択しましょう。
一方で、動的なキー操作、順序の保持、高いパフォーマンスが求められる場合はMapが最適な選択肢となります。
2026年現在のモダンな開発では、Object.groupByのような新しいメソッドも活用しながら、より簡潔で保守性の高いコードを書くことが求められています。
本記事で紹介した各操作法や注意点を、日々のプロジェクトにおける最適な辞書の実装に役立ててください。
