JavaScriptのWeakMapについてのまとめ

image.png (59.9 kB)

TOC

WeakMapとは?

WeakMapは、キーとしてオブジェクトだけを持つことができる特別なマップです。 その主な特徴は、そのキーとして使用されているオブジェクトがガベージコレクションによって削除される場合、そのキーに関連付けられている値もWeakMapから自動的に削除されることです。 これは、オブジェクトとそのオブジェクトに関連付けられた追加の情報をメモリーリークなしに管理するために役立ちます。

WeakMapのメリット

  • メモリリークを防ぐ: WeakMapはキーに対する強い参照を持たないため、不要なオブジェクトがメモリに残り続けることがありません。
  • データのプライバシー: WeakMapのキーは外部から列挙できないため、データを隠蔽するのに適しています。

インスタンスメソッド

WeakMapの基本的なメソッドは以下の通りです:

  1. set(key, value): キーと値をマップに追加します。
  2. get(key): 指定したキーに関連付けられた値を取得します。キーがマップに存在しない場合、undefinedが返されます。
  3. has(key): マップが指定したキーを持っている場合、trueを返します。
  4. delete(key): 指定したキーをマップから削除します。

使用例:

let obj1 = {};
let obj2 = {};

let weakmap = new WeakMap();

weakmap.set(obj1, "object 1");
weakmap.set(obj2, "object 2");

console.log(weakmap.get(obj1));  // "object 1"
console.log(weakmap.has(obj2));  // true

obj1 = null;  // obj1をnullに設定した後、そのキーと関連するエントリはガベージコレクションのタイミングでWeakMapから削除される。

注意点として、WeakMapのキーは列挙できないため、WeakMapに含まれるすべてのキーを取得する方法はありません。これもWeakMapが「弱い」と呼ばれる理由の一部です。

活用例

WeakMapのキーが列挙できない性質は、いくつかの特定のケースで非常に役立ちます。以下はWeakMapの典型的な活用例です:

1. プライベートデータの保持:

WeakMapを使うと、クラスのインスタンスに関連付けられたプライベートデータを保持できます。この方法では、そのデータはクラスの外部から直接アクセスすることはできません。

const privateData = new WeakMap();

class MyClass {
 constructor(data) {
     privateData.set(this, data);
 }

 doSomething() {
     let data = privateData.get(this);
     // ここでdataを使用する...
 }
}

2. イベントリスナーの管理:

イベントリスナーと関連するオブジェクトを管理するときに、WeakMapを使うことで、オブジェクトのライフサイクルに応じてリスナーを自動的にクリーンアップすることができます。

const listenerMap = new WeakMap();

function addListener(obj, event, listener) {
    let listeners = listenerMap.get(obj) || {};
    if (!listeners[event]) {
        listeners[event] = [];
    }
    listeners[event].push(listener);
    listenerMap.set(obj, listeners);
}

function removeListener(obj, event, listener) {
    let listeners = listenerMap.get(obj);
    if (listeners && listeners[event]) {
        listeners[event] = listeners[event].filter(l => l !== listener);
    }
}

function getListeners(obj, event) {
    let listeners = listenerMap.get(obj);
    return listeners ? listeners[event] || [] : [];
}

// 使用例
let obj = {};

function onCustomEvent() {
    console.log('Event triggered!');
}

addListener(obj, 'customEvent', onCustomEvent);
console.log(getListeners(obj, 'customEvent').length); // 1

removeListener(obj, 'customEvent', onCustomEvent);
console.log(getListeners(obj, 'customEvent').length); // 0

// オブジェクトがガベージコレクションされると、それに関連するすべてのイベントリスナーもWeakMapから自動的に削除される
obj = null;

まとめ

WeakMapは、特定のシナリオにおいて非常に有用なデータ構造です。メモリの効率的な管理やデータの隠蔽に役立てることができるため、適切な場面での使用をおすすめします。

CONTACT
© 2023, Kakkiii All Rights Reserved.