JavaScript 速習チュートリアル

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)

これは意図的な設計です。オブジェクトはガベージコレクションによっていつ消滅するか分からないため、それらをカウントしたり、ループで回したりすることには意味がないからです。