Key , Value でオブジェクトを保存する WeakMap

TypeScript の WeakMap は、JavaScript 標準の WeakMap を型安全に扱うためのものです。

参考 : https://ja.javascript.info/weakmap-weakset


基本

  • キーはオブジェクトのみ stringnumber は使えない(object | function | symbol 系が必要)。
  • キーへの参照がなくなると、自動的にGC対象になり、値も破棄される → メモリリーク防止に便利。
  • 列挙不可 for...of.keys() などはない。 (中身を全部見たい用途では使えない)

型の書き方

// WeakMap<キー型, 値型>
const wm = new WeakMap<object, string>();

const obj = {};
wm.set(obj, "hello");

console.log(wm.get(obj)); // "hello"

例: キャッシュ用途

type Data = { id: number; name: string };

const cache = new WeakMap<object, Data>();

function getData(obj: object): Data {
  if (cache.has(obj)) {
    return cache.get(obj)!;
  }
  const data = { id: Math.random(), name: "user" };
  cache.set(obj, data);
  return data;
}

const key = {};
console.log(getData(key)); // 生成されてキャッシュ
console.log(getData(key)); // キャッシュから取得

key が GC で消えると、自動で cache からも消える。


典型的な使い道

  1. オブジェクトにメタ情報を紐付ける クラスインスタンスに「非公開の状態」を持たせたい時など。
  2. キャッシュ 計算コストが高いデータを、オブジェクトに紐付けて保持。
  3. ライブラリ内部の隠しデータストア ユーザーから直接アクセスできない「裏の状態管理」に使える。

注意点

  • イテレーションできないので「全データをまとめて処理する」用途には不向き。
  • Map と違って「キーが生存している限り値を保持、消えれば自動削除」という点が最大のメリット。

ざっくり言えば 「オブジェクトをキーにした隠しデータ置き場。しかもキーが死ねば勝手に消える」

要するに、 Map は「使う人が明示的に管理するキャッシュ」 WeakMap は「GC に任せるキャッシュ」

No.2655
10/14 12:29

edit