「キー付きコレクション(Keyed Collections)」というのは、JavaScript における「キー(key)で値(value)を管理するデータ構造」の総称で、主に以下のものが含まれます:
MapWeakMapSetWeakSet
初心者向けに「なぜこれらがあるのか」「どう使うのか」をステップごとに分かりやすく解説します。
「キー付きコレクション」ですが、「コレクション」は「複数の要素をまとめて扱う構造」という意味です。
1. なぜ “キー付きコレクション” が必要か
普通に JavaScript でデータを管理するとき、オブジェクト({ ... })を使って「キーと値」を対応づけることが多いです。しかしオブジェクトにはいくつか弱点があります:
| 問題点 | 例 | 解決したい性質 |
|---|---|---|
| キーは文字列かシンボルしか使えない | obj[5] としたら実際には "5" という文字列キーになる | 任意の値(オブジェクト、配列、関数など)をキーにできたら便利 |
| プロトタイプに由来するデフォルトのキーと衝突する可能性 | 例えば toString など | 意図しないキーが混ざるのを防ぎたい |
| 要素数を調べるのが面倒 | Object.keys(obj).length などを使わなければならない | size のように即座に数が得られたらいい |
| 挿入順序を保証しない | オブジェクトのキー列挙(for..in など)は挿入順とは限らない | 順序どおりに繰り返したい |
これらを改善したものが「キー付きコレクション」です。たとえば Map は任意の型をキーにでき、要素数も map.size で即座に取得でき、挿入順序で反復できる、という利点があります。
2. Map(マップ)
Map は「キーと値の組を格納するコレクション」で、典型的な使い方は以下の通りです。 MDNウェブドキュメント
基本操作
const myMap = new Map();
// 値を設定(キーと値を対応づける)
myMap.set(key, value);
// 値を取得
myap.get(key);
// キーが存在するかチェック
myMap.has(key);
// キー‐値ペアを削除
myMap.delete(key);
// すべてクリア
myMap.clear();
// 要素数
myMap.size;
JavaScript例
const sayings = new Map();
sayings.set("dog", "woof");
sayings.set("cat", "meow");
sayings.set("elephant", "toot");
console.log(sayings.get("dog")); // "woof"
console.log(sayings.get("fox")); // undefined
console.log(sayings.has("bird")); // false
sayings.delete("dog");
console.log(sayings.has("dog")); // false
for (const [key, value] of sayings) {
console.log(`${key} → ${value}`);
}
// 例の出力順:
// "cat → meow"
// "elephant → toot"
JavaScriptObject と Map の違い・どちらを使うか
Mapのキーはどんな型でも使える(オブジェクト、関数、配列…など)一方、Objectのキーは文字列またはシンボルに自動変換されます。Mapはsizeで要素数がわかるが、Objectだと自前で管理するかObject.keys(obj).lengthのようにする必要がある。Mapは挿入された順に反復できる。Objectはプロトタイプチェーンの影響で、意図しないキー(親オブジェクトのプロパティなど)が見えてしまうことがある。特別な用途ではObject.create(null)を使ってプロトタイプを持たないオブジェクトを作ることもあります。
「どちらを使うべきか」はケースバイケースですが、以下のようなヒントがあります:
3. WeakMap(ウィークマップ)
WeakMap は Map に似ていますが、「弱い参照 (weak reference)」という特殊な性質があります。
特徴
WeakMapのキーは オブジェクトまたは非登録シンボル だけに限定されます(プリミティブ値は使えません)。WeakMapはキーに対して強い参照 (strong reference) を持ちません。つまり、もしそのキーオブジェクトが他のところで参照されなくなれば、ガベージコレクション(不要なメモリ解放)される可能性があります。- 弱い参照を持つという性質上、
WeakMapは列挙 (for…of などで全体を走査) ができません。なぜなら、いつガベージコレクションが発生するか不確定だからです。 WeakMapは、オブジェクトに「プライベートなデータ」を付随させる用途などに使われることがあります。例えば、クラスの外部からはアクセスさせたくない内部状態をWeakMapにキーをthisにして格納しておく、というパターンがあります。
使い方例(簡略)
const privates = new WeakMap();
class MyClass {
constructor(secret) {
privates.set(this, { secretValue: secret });
}
reveal() {
const data = privates.get(this);
console.log(data.secretValue);
}
}
const obj = new MyClass("秘密");
obj.reveal(); // "秘密"
// obj が他で参照されなくなれば、
// privates にある対応するエントリも自動的に解放される可能性がある
JavaScriptこのように、プライベートなデータを外部から直接見えない形で保持する手段として WeakMap が使われます。
4. Set(セット)
Set は「値(value)のコレクション」で、重複を持たず、挿入順で要素を反復できる構造です。
基本操作
const mySet = new Set();
mySet.add(1);
mySet.add("foo");
mySet.add(1); // すでに 1 があるので追加されない(重複しない)
console.log(mySet.has(1)); // true
mySet.delete("foo");
console.log(mySet.size); // 要素数
for (const item of mySet) {
console.log(item);
}
JavaScript配列との変換
Set ⇄ Array の変換は簡単にできます:
const arr = [1, 2, 2, 3];
const s = new Set(arr); // {1, 2, 3}
const uniqueArr = Array.from(s); // [1, 2, 3]
const anotherArr = [...s]; // 同じく [1, 2, 3]
JavaScriptこのように、配列から重複を取り除きたいときに Set を経由することがよくあります。
Set と Array の使い分け
- 値が重複してはいけない、という保証を持たせたいときは
Setが便利。 - 特定の要素の追加・削除・検索を高速に行いたいときも
Setは有利(ただし規模や利用頻度にもよる)。 - 順序を保ちたい、かつ重複排除をしたい場面では
Setが適している。
5. WeakSet(ウィークセット)
WeakSet は Set の弱参照版、かつキー版とは少し異なる制約があります。
特徴
WeakSetに格納できる値は オブジェクトまたは非登録シンボル のみ。プリミティブ値(数値や文字列など)は格納できません。WeakSetに入れたオブジェクトが他で参照されなくなれば、ガベージコレクションの対象になります(弱参照)。WeakSetは列挙できません(どの要素が入っているか一覧で取得する API がありません)。これは、ガベージコレクションのタイミングが不確定なためです。
主な用途
DOM 要素のマーク、あるオブジェクトが「既に処理されたかどうか」を記録しておくなど、**オブジェクトに対して一時的に「フラグをつける」**用途で使われることがあります。
6. Map/Set における等価性の判定 ― SameValueZero アルゴリズム
Map(キー)と Set(値)で「同じかどうか」を判定する際には、JavaScript の厳密等価演算子 === に近いルールが使われますが、少し異なる点があります。MDN ではこれを “SameValueZero” アルゴリズムと呼んでいます。
- 原則として
===と同じ挙動をします。 - ただし、
-0と+0は等しいとみなされます。 NaNは===では等しくない(NaN === NaNはfalse)ですが、SameValueZero ではNaNは自身と等しいとみなされます。
つまり、Map のキーや Set の要素として NaN を使っても、正しく “存在” と “重複排除” が働きます。
7. まとめ(初心者向けのポイント整理)
- 「キー付きコレクション」とは、キー(または値)で要素を管理する仕組みの総称で、
Map,WeakMap,Set,WeakSetが含まれる。 Mapはキーと値を対応づけて扱える、オブジェクトより高機能な構造。WeakMapはキーがオブジェクト限定で、弱参照を使う(ガベージコレクションと連動する)もの。Setは値のコレクションで、重複を許さず順序を保持する。WeakSetはオブジェクト限定で弱参照を使う、列挙できない Set のようなもの。- 等価性の判定には “SameValueZero” というルールが使われ、
NaNの扱いや+0/−0の扱いが===とは少し違う。
