WeakSet

Baseline Widely available *

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

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

WeakSet — это набор значений, поддерживающих сборку мусора, включая объекты и незарегистрированные символы. Каждое значение в WeakSet может встречаться только один раз, оно уникально в коллекции WeakSet.

Описание

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

Ключевые отличия от Set:

  • WeakSet — это набор только объектов и символов. В отличие от Set он не может содержать произвольные значения любого типа.

  • WeakSet является слабым в том смысле, что ссылки на объекты в WeakSet хранятся слабо. Если нет других ссылок на значение, хранящееся в WeakSet, эти значения могут быть удалены сборщиком мусора.

    Примечание: Это также означает, что нет списка текущих значений сохранённых в наборе. Объекты WeakSet не перечислимы.

Вариант использования: обнаружение циклических ссылок

Функциям, которые вызывают себя рекурсивно, необходим способ защиты от циклических структур данных путём отслеживания того, какие объекты уже были обработаны.

Объекты WeakSet идеально подходят для этого:

js
// Выполняем `fn` для всего, что хранится внутри объекта.
function execRecursively(fn, subject, _refs = new WeakSet()) {
  // Избегаем бесконечно рекурсии
  if (_refs.has(subject)) {
    return;
  }

  fn(subject);
  if (typeof subject === "object" && subject) {
    _refs.add(subject);
    for (const key in subject) {
      execRecursively(fn, subject[key], _refs);
    }
    _refs.delete(subject);
  }
}

const foo = {
  foo: "Foo",
  bar: {
    bar: "Bar",
  },
};

foo.bar.baz = foo; // Циклическая ссылка!
execRecursively((obj) => console.log(obj), foo);

Здесь WeakSet создаётся при первом запуске и передаётся вместе с каждым последующим вызовом функции (с использованием внутреннего параметра _refs).

Количество объектов или порядок их обхода не имеют значения, поэтому использование WeakSet более эффективно, чем Set для отслеживания ссылок на объекты, особенно если задействовано очень большое количество объектов.

Конструктор

WeakSet()

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

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

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

WeakSet.prototype.constructor

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

WeakSet.prototype[@@toStringTag]

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

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

WeakSet.prototype.add()

Добавляет value в объект WeakSet.

WeakSet.prototype.delete()

Удаляет value из WeakSet. После этого WeakSet.prototype.has(value) будет возвращать false.

WeakSet.prototype.has()

Возвращает булево значение, показывающее присутствует ли value в объекте WeakSet или нет.

Примеры

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

js
const ws = new WeakSet();
const foo = {};
const bar = {};

ws.add(foo);
ws.add(bar);

ws.has(foo); // true
ws.has(bar); // true

ws.delete(foo); // удаляем foo из набора
ws.has(foo); // false, foo был удалён
ws.has(bar); // true, bar сохранился

Обратите внимание, что foo !== bar. Хотя это похожие объекты, это не один и тот же объект. И поэтому они оба добавляются в набор.

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

Specification
ECMAScript® 2025 Language Specification
# sec-weakset-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
WeakSet
WeakSet() constructor
new WeakSet(iterable)
new WeakSet(null)
add
delete
has
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.

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