WeakMap

Baseline Widely available *

This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.

* Some parts of this feature may have varying levels of support.

WeakMap — это коллекция пар ключ-значение. В качестве ключей могут быть использованы только объекты и незарегистрированные символы, а значения могут быть произвольных типов.

Описание

Ключи в WeakMap должны поддерживать сборку мусора. Большинство примитивных типов данных могут не иметь времени жизни, поэтому они не могут быть использованы в качестве ключей. Объекты и незарегистрированные символы могут быть ключами потому что они поддерживают сборку мусора.

Почему WeakMap?

Опытный JavaScript разработчик заметит, что map API можно реализовать на JavaScript c помощью двух массивов (один для ключей, второй для значений) и четырёх общих API методов. Установка элементов в этот map должна будет одновременно запушить ключи и значения. В результате индексы ключа и значения будут корректными. Получение значений с map потребует итерирование ключей, чтобы найти совпадение, а затем использование индекса этого соответствия для извлечения соответствующего значения из массива значений.

У такой реализации было бы два главных неудобства. Первым является O(n) поиск (где n — количество ключей в map), так как обе операции требуют итерирование списка ключей для нахождения совпадения. Вторым — проблема утечки памяти. В словарях, написанных вручную, массив с ключами будет хранить ссылки на объекты-ключи, не давая им быть помеченными сборщиком мусора. В нативных WeakMap, ссылки на объекты-ключи хранятся «слабо», что означает то, что они не предотвратят сборку мусора в том случае, если других ссылок на объект не будет.

WeakMaps имеют "weak" («слабые») обращения к ключам объекта, а следовательно непрепятствие сборщику мусора, когда мы больше не имеем объекта-ключа. WeakMaps могут быть особенно полезными конструкциями при сопоставлении ключей с информацией о ключе, который ценен, только если ключ не был собран сборщиком мусора (Garbage collector).

Из-за того, что ссылки являются слабыми, ключи WeakMap не перечисляемы (то есть нет метода, который возвращает список ключей). Иначе список бы зависел от состояния сбора мусора, представляя индетерминизм. Если вы хотите иметь список ключей, вам следует поддерживать его самостоятельно.

Конструктор

WeakMap()

Создаёт новый объект WeakMap.

Свойства экземпляра

Эти свойства определены в WeakMap.prototype и есть у всех экземпляров WeakMap.

WeakMap.prototype.constructor

Функция-конструктор, создающая экземпляр объекта. Для экземпляров WeakMap начальным значением является конструктор WeakMap.

WeakMap.prototype[@@toStringTag]

Начальным значением свойства @@toStringTag является строка "WeakMap". Это свойство используется в Object.prototype.toString().

Методы экземпляра

WeakMap.prototype.delete()

Удаляет значение, связанное с ключом key. После этого WeakMap.prototype.has(key) будет возвращать false.

WeakMap.prototype.get()

Возвращает значение, связанное с ключом key или undefined если его нет.

WeakMap.prototype.has()

Возвращает булево значение, показывающее связано ли значение с ключом key в объекте WeakMap или нет.

WeakMap.prototype.set()

Устанавливает значение value для ключа key в объекте WeakMap. Возвращает объект WeakMap.

Примеры

Использование WeakMap

js
const wm1 = new WeakMap();
const wm2 = new WeakMap();
const wm3 = new WeakMap();
const o1 = {};
const o2 = function () {};
const o3 = window;

wm1.set(o1, 37);
wm1.set(o2, "Привет");
wm2.set(o1, o2); // значением может быть что угодно, включая объект или функцию
wm2.set(o2, undefined);
wm2.set(wm1, wm2); // ключами и значениями могут быть объекты и даже WeakMap (!)

wm1.get(o2); // "Привет"
wm2.get(o2); // undefined, потому что такое значение было установлено
wm2.get(o3); // undefined, потому что в wm2 нет ключа o3

wm1.has(o2); // true
wm2.has(o2); // true (даже если само значение равно 'undefined')
wm2.has(o3); // false

wm3.set(o1, 37);
wm3.get(o1); // 37

wm1.has(o1); // true
wm1.delete(o1);
wm1.has(o1); // false

Пример: Реализация класса WeakMap-подобных классов с методом .clear()

js
class ClearableWeakMap {
  #wm;
  constructor(init) {
    this.#wm = new WeakMap(init);
  }
  clear() {
    this.#wm = new WeakMap();
  }
  delete(k) {
    return this.#wm.delete(k);
  }
  get(k) {
    return this.#wm.get(k);
  }
  has(k) {
    return this.#wm.has(k);
  }
  set(k, v) {
    this.#wm.set(k, v);
    return this;
  }
}

Спецификации

Specification
ECMAScript® 2025 Language Specification
# sec-weakmap-objects

Совместимость с браузерами

Report problems with this compatibility data on GitHub
desktopmobileserver
Chrome
Edge
Firefox
Opera
Safari
Chrome Android
Firefox for Android
Opera Android
Safari on iOS
Samsung Internet
WebView Android
WebView on iOS
Deno
Node.js
WeakMap
WeakMap() constructor
new WeakMap(iterable)
new WeakMap(null)
delete
get
has
set
Non-registered symbols as keys

Legend

Tip: you can click/tap on a cell for more information.

Full support
Full support
No support
No support
See implementation notes.

Смотрите также