WeakMap と WeakSet は、JavaScript における特殊なコレクション型です。これらは、通常の Map や Set と似たような役割を持ちますが、メモリ管理に関して異なる特徴を持っています。特に、弱い参照を使用することによって、ガーベジコレクション(GC)における挙動が変わる点が大きな特徴です。
1. WeakMap とは?
WeakMap は、オブジェクトをキーとして、値を関連付けることができるコレクションです。通常の Map ではキーとして任意の値を使うことができますが、WeakMap ではキーとして使用できるのは「オブジェクト」だけです。つまり、プリミティブ型(例えば文字列や数値)をキーとして使用することはできません。
特徴:
-
弱い参照(Weak References):
WeakMapのキーは弱い参照として保持されます。これは、キーとなるオブジェクトが他の場所から参照されなくなると、そのオブジェクトがガーベジコレクションの対象となることを意味します。つまり、WeakMapのキーとして使っているオブジェクトが不要になると、メモリが自動的に解放されます。 -
サイズ取得不可:
WeakMapはサイズを取得する方法を提供していません。つまり、WeakMap内に何個のエントリーがあるかを直接知ることはできません。 -
反復不可能:
WeakMapは反復(イテレーション)操作ができません。つまり、forEachなどの方法でWeakMapの全てのエントリーを列挙することはできません。
使用例:
javascriptlet weakMap = new WeakMap();
let obj = {};
weakMap.set(obj, "value");
console.log(weakMap.get(obj)); // "value"
obj = null; // objが弱い参照であるため、ガーベジコレクションでメモリ解放される
このコードでは、obj が WeakMap に登録されている間は、obj を使ってその値にアクセスできます。しかし、obj を null に設定すると、obj の参照がなくなるため、WeakMap からも自動的に削除され、メモリが解放されます。
2. WeakSet とは?
WeakSet は、オブジェクトのみを要素として保持できるセット(集合)です。通常の Set と異なり、WeakSet の要素も弱い参照で保持されます。これは、要素が他の場所で参照されなくなると、自動的にメモリから解放されることを意味します。
特徴:
-
弱い参照:
WeakSetに格納されたオブジェクトは、弱い参照として保持されます。これにより、ガーベジコレクションの対象となると、そのオブジェクトは自動的にWeakSetから削除されます。 -
重複しない要素:
WeakSetもSetと同様に、重複する要素を持つことがありません。つまり、同じオブジェクトを複数回WeakSetに追加しようとしても、実際には1つの要素として扱われます。 -
反復不可能:
WeakSetもWeakMapと同様に、反復操作ができません。WeakSet内の全ての要素を列挙することはできません。
使用例:
javascriptlet weakSet = new WeakSet();
let obj1 = {};
let obj2 = {};
weakSet.add(obj1);
weakSet.add(obj2);
console.log(weakSet.has(obj1)); // true
console.log(weakSet.has(obj2)); // true
obj1 = null; // obj1がガーベジコレクションで解放される
console.log(weakSet.has(obj1)); // false
ここでは、obj1 と obj2 を WeakSet に追加していますが、obj1 を null に設定すると、obj1 がガーベジコレクションで解放され、WeakSet からも削除されます。
3. WeakMap と WeakSet の違い
-
用途の違い:
WeakMapはオブジェクトをキーとして、値を関連付けるためのコレクションです。一方、WeakSetはオブジェクトのみを要素として格納できる集合です。 -
メモリ管理: 両方とも、格納されているオブジェクトが他の場所から参照されなくなると、そのオブジェクトはガーベジコレクションの対象となり、メモリが解放されます。しかし、
WeakMapはキーと値のペアを保持するのに対し、WeakSetは単にオブジェクトの存在を管理します。
4. 使用場面
WeakMap と WeakSet は、特に以下のようなシナリオで有用です:
-
メモリ管理: 多くのオブジェクトを動的に保持しつつ、そのオブジェクトが他で参照されなくなった際にメモリを自動的に解放したい場合に有用です。
-
キャッシュ機構: 例えば、オブジェクトをキーとして、関連するデータを保持するようなキャッシュ機構を作る場合に、
WeakMapを使うと便利です。キャッシュのキーとなるオブジェクトが不要になった場合に、自動的にそのデータも削除されます。 -
オブジェクトの監視:
WeakSetを使って、特定のオブジェクトの状態を監視したり、処理の対象として保持したりすることができます。オブジェクトが不要になれば、自動的にWeakSetからも削除されます。
5. 結論
WeakMap と WeakSet は、ガーベジコレクションを活用してメモリ管理を最適化するための強力なツールです。これらは、特にオブジェクトが不要になったときにそのメモリを自動的に解放したい場合に役立ちます。しかし、これらは通常の Map や Set と異なり、反復やサイズの取得などができないため、用途に応じて適切に使い分けることが重要です。
