WeakSet
WeakSet
— это набор значений, поддерживающих сборку мусора, включая объекты и незарегистрированные символы. Каждое значение в WeakSet
может встречаться только один раз, оно уникально в коллекции WeakSet
.
Описание
Значения в WeakSet должны поддерживать сборку мусора. Большинство примитивных типов данных могут не иметь времени жизни, поэтому они не могут быть сохранены. Объекты и незарегистрированные символы могут быть сохранены потому что они поддерживают сборку мусора.
Ключевые отличия от Set
:
WeakSet
— это набор только объектов и символов. В отличие отSet
он не может содержать произвольные значения любого типа.WeakSet
является слабым в том смысле, что ссылки на объекты вWeakSet
хранятся слабо. Если нет других ссылок на значение, хранящееся вWeakSet
, эти значения могут быть удалены сборщиком мусора.Примечание: Это также означает, что нет списка текущих значений сохранённых в наборе. Объекты
WeakSet
не перечислимы.
Вариант использования: обнаружение циклических ссылок
Функциям, которые вызывают себя рекурсивно, необходим способ защиты от циклических структур данных путём отслеживания того, какие объекты уже были обработаны.
Объекты WeakSet
идеально подходят для этого:
// Выполняем `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
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 Language Specification # sec-weakset-objects |
Совместимость с браузерами
BCD tables only load in the browser