まずゴールをはっきりさせる:何を判断したいのか
ES6 の「新データ構造」と言われると、
- Map / Set
- WeakMap / WeakSet
が一気に出てきて、「全部使えたほうがいいのかな?」と身構えがちです。
でも実務的には、いきなり全部をフル活用する必要はありません。
実務で大事なのは、
- どんな場面で
「Object / Array より Map / Set を選ぶべきか」 - どんな場面で
「WeakMap / WeakSet を使う“価値がある”のか」
を見分けられることです。
ここが重要です。
「何でも新データ構造を使う」のではなく、「こういうときはこれ」と選べることが、実務での強さになります。
実務でよく使うのは「Map」と「Set」
まず優先度:Map / Set を日常的な武器にする
実務レベルで本当によく使うのは、断トツで Map と Set です。
WeakMap / WeakSet は「知っておくと得」くらいで、
毎日のように出てくるのは Map / Set の方です。
ですから判断のスタート地点はこうです。
- これは Object / Array で書いているけど、
Map / Set にしたほうが素直じゃないか?
この視点で、自分のコードを見直してみるのが一番現実的です。
Array vs Set:重複・存在チェック・集合っぽさ
次のようなコードを書いていたら、Set を検討する価値が高いです。
- 配列に値をどんどん push している
- その前に
includesやindexOfで「もう入ってるかどうか」をチェックしている - 「重複を消したい」と思っている
典型的な例を見てみます。
// よくある「配列だけで頑張る」パターン
const visited = [];
function visit(page) {
if (!visited.includes(page)) {
visited.push(page);
}
}
JavaScriptこれが Set だとこうなります。
const visited = new Set();
function visit(page) {
visited.add(page); // 重複なら自動で無視
}
JavaScript「重複を気にする」仕事を Set に丸投げできるので、
コードが短くなるだけでなく、意図が明確になります。
ここが重要です。
「要素の順番+重複OK」なら Array。
「順番+重複NG」なら Set。
この軸で考えると、「どちらを使うべきか」の判断がかなり楽になります。
Object vs Map:辞書・マップらしく扱いたいとき
次のようなコードを書いていたら、Map を検討する価値が高いです。
- Object に動的にキーを追加・削除している
- 「キーの数」を頻繁に知りたい
- 「存在チェック」「削除」をよくする
- キーに数値やオブジェクトを使いたい
よくある「ユーザーID → ユーザー」を Object でやるケース:
// Object で辞書をやっている例
const users = {};
function addUser(user) {
users[user.id] = user;
}
function getUser(id) {
return users[id];
}
function getUserCount() {
return Object.keys(users).length;
}
JavaScriptこれを Map にすると:
const users = new Map();
function addUser(user) {
users.set(user.id, user);
}
function getUser(id) {
return users.get(id);
}
function getUserCount() {
return users.size;
}
JavaScriptサイズ取得、存在チェック、削除、ループなど、
すべて Map のメソッドで書けて、コードの意図がかなり読みやすくなります。
ここが重要です。
「1件のデータの属性」なら Object、「たくさんのキーと値の集まり」なら Map。
実務では、このラインを意識するだけで設計の見通しが一段上がります。
具体的な判断フロー(Map / Set を使うか?)
まず自分に問うべき質問
コードを書いていて迷ったら、こんな質問を自分に投げてみてください。
これは「1件の情報」か?「たくさんの集まり」か?
- 1人のユーザーの id, name, age → Object
- たくさんのユーザーを id で引きたい → Map
// Object が自然
const user = { id: 1, name: "Alice", age: 20 };
// Map が自然
const userById = new Map();
userById.set(1, user);
JavaScript重複を許したいか?許したくないか?
- 同じ値が何度も登場してもいい履歴 → Array
- 「一度でも登場したかどうか」が本質 → Set
// クリック履歴(何度クリックされたかも意味がある)→ Array
const clickHistory = [];
// どのページを一度でも訪れたかだけが重要 → Set
const visitedPages = new Set();
JavaScriptキーにオブジェクトを使いたいか?
- 使わない(文字列 / 数値キーだけ) → Object or Map
- 使いたい(DOM 要素やオブジェクトそのもの) → Map 一択
// DOM 要素に追加情報を紐づけたい
const stateByElement = new Map();
stateByElement.set(someDomElement, { hovered: false });
JavaScript実務的な優先順位
実用順に並べると、こうなります。
- Array / Object(これがベース)
- そこから卒業する形で Set / Map
- さらに特殊な場面で WeakMap / WeakSet
無理に「最初から全部新データ構造で!」としなくてよくて、
Array / Object で書いたものを、
- 「これ、Set / Map の方が意味としてしっくりくるな」
- 「ここ、includes / Object.keys.length を何度も書いていてダルいな」
というポイントから少しずつ置き換えていく方が、身になり方も現実的です。
WeakMap / WeakSet を実務で使うかどうかの判断
結論:初心者は「存在を知っておけば十分」
正直にいうと、
フロントエンドでもバックエンドでも、WeakMap / WeakSet を毎日触る人はそんなに多くありません。
ただし、「ここで WeakMap 使えるな」と気づける人は、
メモリや設計に対する感度が高いです。
なので、初心者のうちは:
- 「オブジェクトに付随情報を持たせたい」
- 「でも、そのせいでメモリリークさせたくない」
という状況が見えたときに、
「そういえば WeakMap / WeakSet ってあったな」と思い出せれば十分です。
実務で WeakMap / WeakSet を使うべき条件
次の 2 つが揃っていたら、Weak 系を検討する価値があります。
- キー or 要素に「オブジェクト(特に DOM やクラスインスタンス)」を使いたい
- そのオブジェクトが不要になったとき、「自動で紐づいた情報も消えてほしい」(= メモリリークを避けたい)
例えば、DOM 要素 → 付随情報のマップ:
// WeakMap の利用が検討できるパターン
const extraData = new WeakMap();
function attach(el, data) {
extraData.set(el, data);
}
function getData(el) {
return extraData.get(el);
}
JavaScriptここで普通の Map を使うと、
- DOM を削除しても
- Map が要素を参照し続けるので
- GC で回収されない → メモリリークのリスク
WeakMap なら、要素が他から参照されなくなれば、
付随情報ごと GC の対象になります。
「一覧したい」「数えたい」なら Weak 系は選ばない
次のように思った瞬間、WeakMap / WeakSet は候補から外れます。
- 中身を全部ループしたい
- 何個登録されているか size で見たい
Weak 系はそもそも「列挙もサイズもできない設計」なので、
そういう用途には向きません。
ここが重要です。
WeakMap / WeakSet は、「既に知っているオブジェクトに対して、こっそり情報をくっつける」ためのツール。
全体を管理・監視するツールではない。
小さな実務風シナリオで判断を体感する
シナリオ1:ToDo アプリの内部データ
ToDo アプリを考えます。
- 1 件のタスク(id, title, done) → Object
- タスクの一覧 → Array or Map?
ここではこう分けるのが自然です。
// 1件のタスク
const todo = {
id: 1,
title: "牛乳を買う",
done: false,
};
// タスク一覧(ID で検索したいなら Map が便利)
const todosById = new Map();
todosById.set(todo.id, todo);
JavaScript- 「表示順」が大事なら Array(+必要に応じて Map を併用)
- 「id から一発で取りたい」が大事なら Map
という風に、「何が一番大事な操作か」で選びます。
シナリオ2:ログイン中ユーザーの管理
- 要件:ユーザーIDごとに「ログイン中のユーザー情報」を持ちたい
- 操作:ログイン / ログアウト / 現在のログイン人数
こういう要件は Map がぴったりです。
const loggedInUsers = new Map();
function login(user) {
loggedInUsers.set(user.id, user);
}
function logout(userId) {
loggedInUsers.delete(userId);
}
function getCurrentUserCount() {
return loggedInUsers.size;
}
JavaScriptここを普通の Object でやると、Object.keys(users).length が出てきたりして、
「辞書を頑張って自前実装している」感じになります。
シナリオ3:イベント登録済みの DOM を覚えておく
- 要件:同じ DOM 要素に何度もイベントを登録したくない
- DOM は消えることもあり、そのとき余計な情報も消えてほしい
ここは WeakSet を検討できます。
const registered = new WeakSet();
function ensureClickHandler(el) {
if (registered.has(el)) return;
el.addEventListener("click", () => {
console.log("clicked");
});
registered.add(el);
}
JavaScriptDOM が削除され、他からも参照されなくなれば、
WeakSet 内の記録も GC により消えます。
同じことを Set でやると、
「削除された DOM への参照」が残り続け、
メモリをじわじわ食い続ける可能性があります。
まとめ:新データ構造を「いつ実務に投入するか」
最後に、実務での判断をシンプルな軸にまとめます。
Map / Set を使うべきか?
自分のコードにこういう症状が出ていたら、Map / Set を検討してよいサインです。
- Object を「辞書」のように扱っている(動的にキーを増やす・消す・数える)
- 配列+
includesで「重複チェック」をよく書いている - ある ID やキーから、対応するデータを即座に引きたい
- 要素数(サイズ)を頻繁に知りたい
このどれかに当てはまるなら、
Array / Object から Map / Set に一歩踏み出していいタイミングです。
WeakMap / WeakSet を使うべきか?
次の条件を満たしたときだけです。
- キー or 要素に「オブジェクト(特に DOM / インスタンス)」を使いたい
- そのオブジェクトが不要になったとき、自動で追加情報も消えてほしい
- 中身を列挙したり、個数を数えたりする必要はない
それ以外の場面では、
「まず Map / Set でいいか?」と考えるほうが安全です。
最初から正解を一発で選べる必要はありません。
大事なのは、こうやって
- これは「集合」だから Set
- これは「辞書」だから Map
- これは「1件のデータ」だから Object
と、自分なりの言葉で説明できるようになることです。
そこまで来たら、あなたはすでに「実務で新データ構造を判断して使いこなせる人」の入り口にいます。
あとは、自分の既存コードの一部を少しずつ Map / Set に置き換えていく中で、
「どこが楽になったか」「どこが気持ちいいか」を、実感で掴んでいってください。

