プログラミング

WeakMap と WeakSet の解説

WeakMapWeakSet は、JavaScript における特殊なコレクション型です。これらは、通常の MapSet と似たような役割を持ちますが、メモリ管理に関して異なる特徴を持っています。特に、弱い参照を使用することによって、ガーベジコレクション(GC)における挙動が変わる点が大きな特徴です。

1. WeakMap とは?

WeakMap は、オブジェクトをキーとして、値を関連付けることができるコレクションです。通常の Map ではキーとして任意の値を使うことができますが、WeakMap ではキーとして使用できるのは「オブジェクト」だけです。つまり、プリミティブ型(例えば文字列や数値)をキーとして使用することはできません。

特徴:

  • 弱い参照(Weak References): WeakMap のキーは弱い参照として保持されます。これは、キーとなるオブジェクトが他の場所から参照されなくなると、そのオブジェクトがガーベジコレクションの対象となることを意味します。つまり、WeakMap のキーとして使っているオブジェクトが不要になると、メモリが自動的に解放されます。

  • サイズ取得不可: WeakMap はサイズを取得する方法を提供していません。つまり、WeakMap 内に何個のエントリーがあるかを直接知ることはできません。

  • 反復不可能: WeakMap は反復(イテレーション)操作ができません。つまり、forEach などの方法で WeakMap の全てのエントリーを列挙することはできません。

使用例:

javascript
let weakMap = new WeakMap(); let obj = {}; weakMap.set(obj, "value"); console.log(weakMap.get(obj)); // "value" obj = null; // objが弱い参照であるため、ガーベジコレクションでメモリ解放される

このコードでは、objWeakMap に登録されている間は、obj を使ってその値にアクセスできます。しかし、objnull に設定すると、obj の参照がなくなるため、WeakMap からも自動的に削除され、メモリが解放されます。

2. WeakSet とは?

WeakSet は、オブジェクトのみを要素として保持できるセット(集合)です。通常の Set と異なり、WeakSet の要素も弱い参照で保持されます。これは、要素が他の場所で参照されなくなると、自動的にメモリから解放されることを意味します。

特徴:

  • 弱い参照: WeakSet に格納されたオブジェクトは、弱い参照として保持されます。これにより、ガーベジコレクションの対象となると、そのオブジェクトは自動的に WeakSet から削除されます。

  • 重複しない要素: WeakSetSet と同様に、重複する要素を持つことがありません。つまり、同じオブジェクトを複数回 WeakSet に追加しようとしても、実際には1つの要素として扱われます。

  • 反復不可能: WeakSetWeakMap と同様に、反復操作ができません。WeakSet 内の全ての要素を列挙することはできません。

使用例:

javascript
let 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

ここでは、obj1obj2WeakSet に追加していますが、obj1null に設定すると、obj1 がガーベジコレクションで解放され、WeakSet からも削除されます。

3. WeakMapWeakSet の違い

  • 用途の違い: WeakMap はオブジェクトをキーとして、値を関連付けるためのコレクションです。一方、WeakSet はオブジェクトのみを要素として格納できる集合です。

  • メモリ管理: 両方とも、格納されているオブジェクトが他の場所から参照されなくなると、そのオブジェクトはガーベジコレクションの対象となり、メモリが解放されます。しかし、WeakMap はキーと値のペアを保持するのに対し、WeakSet は単にオブジェクトの存在を管理します。

4. 使用場面

WeakMapWeakSet は、特に以下のようなシナリオで有用です:

  • メモリ管理: 多くのオブジェクトを動的に保持しつつ、そのオブジェクトが他で参照されなくなった際にメモリを自動的に解放したい場合に有用です。

  • キャッシュ機構: 例えば、オブジェクトをキーとして、関連するデータを保持するようなキャッシュ機構を作る場合に、WeakMap を使うと便利です。キャッシュのキーとなるオブジェクトが不要になった場合に、自動的にそのデータも削除されます。

  • オブジェクトの監視: WeakSet を使って、特定のオブジェクトの状態を監視したり、処理の対象として保持したりすることができます。オブジェクトが不要になれば、自動的に WeakSet からも削除されます。

5. 結論

WeakMapWeakSet は、ガーベジコレクションを活用してメモリ管理を最適化するための強力なツールです。これらは、特にオブジェクトが不要になったときにそのメモリを自動的に解放したい場合に役立ちます。しかし、これらは通常の MapSet と異なり、反復やサイズの取得などができないため、用途に応じて適切に使い分けることが重要です。

Back to top button