JavaScript ウィークセット
1. WeakSet オブジェクトの概要
JavaScript の WeakSet は、値がオブジェクトのみに限定されたコレクションです。
WeakSet は、その値に対して「弱参照 (Weak Reference)」を保持します。
例
// WeakSet を作成します
let mySet = new WeakSet();
// オブジェクトを作成します
let myObj = {fname: "太郎", lname: "山田"};
// オブジェクトを追加します
mySet.add(myObj);
// mySet 内に myObj が存在するか確認します
let answer = mySet.has(myObj);例(削除操作)
// WeakSet を作成します
let mySet = new WeakSet();
// オブジェクトを作成します
let myObj = {fname: "太郎", lname: "山田"};
// オブジェクトを追加します
mySet.add(myObj);
// オブジェクトを削除します
mySet.delete(myObj);
// 存在確認(結果は false になります)
let answer = mySet.has(myObj);2. ガベージコレクション (Garbage Collection)
JavaScript は、ガベージコレクション(Garbage Collection) と呼ばれるメモリ管理メカニズムを採用しています。
その主な役割は以下の通りです:
- メモリリソースの効率的な利用を確保する
- 使用されなくなった変数が占有しているメモリを回収する
- メモリリーク (Memory Leak) を防止する
3. 弱参照 (Weak References)
通常の Set とは異なり、WeakSet はその値がガベージコレクションされるのを妨げません。
プログラム内でそのオブジェクト(値)への参照が他になくなった場合、そのオブジェクトはガベージコレクションの対象となります。
オブジェクトがメモリから回収されると、WeakSet からも自動的に削除されます。
例
// WeakSet を作成します
let mySet = new WeakSet();
// オブジェクトを作成します
let myObj = {fname: "太郎", lname: "山田"};
// オブジェクトを追加します
mySet.add(myObj);
// メモリ上のオブジェクト参照を解除します
myObj = null;
// これにより、mySet 内のオブジェクトは自動的にガベージコレクションされます4. 要素はオブジェクトである必要がある
WeakSet の要素として、プリミティブ値 (Primitive values) を使用することはできません。
要素は必ずオブジェクトである必要があります。
この制限はガベージコレクションの仕組みに密接に関係しています。プリミティブ値は、オブジェクトと同じような方法でガベージコレクションが行われないためです。
5. オブジェクトの追跡 (Tracking Objects)
WeakSet は Set と似ていますが、オブジェクトのみを格納し、それらを弱く保持します。オブジェクトへの他の参照がなくなった場合、自動的に回収されます。
これにより、余計なデータ(カウントなど)を保持せずにオブジェクトを追跡するのに非常に便利です。
例:訪問者の追跡
let text = "";
// 訪問者を追跡するための WeakSet を作成します
const persons = new WeakSet();
// 訪問者オブジェクト
const John = {name: "ジョン", age: 40};
const Paul = {name: "ポール", age: 41};
const Ringo = {name: "リンゴ", age: 42};
const George = {name: "ジョージ", age: 43};
// 訪問を記録します
track(Paul);
track(Ringo);
track(Paul);
// 訪問者を追跡するファンクション
function track(visitor) {
if (persons.has(visitor)) {
text += visitor.name + " さんが再訪問しました。<br>";
} else {
persons.add(visitor);
text += visitor.name + " さん(" + visitor.age + "歳)が初めて訪問しました。<br>";
}
}訪問回数などもカウントしたい場合は、WeakSet ではなく WeakMap の使用を検討してください。
6. 自動クリーンアップ (Automatic Cleanup)
訪問者オブジェクトへのすべての参照を削除すると、自動的にクリーンアップされます。
例:参照の解除
John = null;
// John への参照がなくなったため、WeakSet (persons) からもエントリが自動的に削除されます7. 反復処理は不可 (Not Iterable)
WeakSet は 列挙可能(Enumerable)ではありません。
forループ、forEach()、values()などを使用して値を反復処理(Iteration)することはできません。- 要素数にアクセスすることはできません。WeakSet には size プロパティが存在しません。
8. 限定されたメソッド (Limited Methods)
WeakSet は、オブジェクトをプライベートかつ効率的に追跡するために特化した、メモリ安全でミニマルな設計になっています。
提供されているメソッドは以下の通りです:
| メソッド | 説明 |
|---|---|
new WeakSet() | 新しい WeakSet オブジェクトを作成します |
add(object) | オブジェクトを WeakSet に追加します |
delete(object) | WeakSet からオブジェクトを削除します |
has(object) | オブジェクトが存在する場合に true を返します |
WeakSet に存在しないもの:
sizeプロパティ- スプレッド演算子 (
...) clear()メソッド- 集合演算メソッド (
union,difference,intersectionなど) - イテレーションメソッド (
forEach,keys,values,entries)
これは意図的な設計です。オブジェクトはガベージコレクションによっていつ消滅するか分からないため、それらをカウントしたり、ループで回したりすることには意味がないからです。