03. Weak Collections
Коллекции со слабыми ссылками (weak references) отличаются стратегией хранения объектов: если некий объект присутствует только в коллекции со слабыми ссылками, то сборщику мусора разрешается очищать из памяти данный объект. Ключами таких коллекций обязаны быть объекты, а значениями -- произвольные значения.
Классы WeakSet/WeakMap
полезны для ситуаций в которых вы ассоциируете данные с объектами, чей жизненный цикл вы не собираетесь контролировать:
Кэширование промежуточных результатов
Сохранение временных приватных данных
WeakMap
WeakMap
WeakMap
- это карта со слабыми ключами. WeakMap
избавляет нас от необходимости вручную удалять вспомогательные данные (значения карты), когда удалён основной объект.
const wm = new WeakMap();
wm.set("abc", 123); // TypeError
wm.set({}, 123); // OK
У WeakMap
есть ряд ограничений:
Ключами обязаны быть только объекты
Нет свойства
size
.Нельзя узнать содержимое карты
Нельзя перебрать элементы итератором или
forEach
.Нет метода
clear()
.Не является итерируемыми
WeakMap
работает только на запись (set
, delete
) и чтение (get
, has
) элементов по конкретному ключу, а не как полноценная коллекция. Нельзя вывести всё содержимое WeakMap
, нет соответствующих методов.
Содержимое WeakMap
в произвольный момент, строго говоря, не определено. Может быть, сборщик мусора уже удалил какие-то записи, а может и нет. С этим, а также с требованиями к эффективной реализации WeakMap
, и связано отсутствие методов, осуществляющих доступ ко всем записям. Содержимое WeakMap
может быть модифицировано сборщиком мусора в любой момент, независимо от программиста. Сборщик мусора работает сам по себе. Он не гарантирует, что очистит объект сразу же, когда это стало возможным. В равной степени он не гарантирует и обратное. Нет какого-то конкретного момента, когда такая очистка точно произойдёт — это определяется внутренними алгоритмами сборщика и его сведениями о системе.
Пример:
const cache = new WeakMap();
function countOwnKeys(obj) {
if (cache.has(obj)) {
console.log("Cached");
return cache.get(obj);
} else {
console.log("Computed");
const count = Object.keys(obj).length;
cache.set(obj, count);
return count;
}
}
WeakSet
WeakSet
WeakSet
— особый вид Set
не препятствующий сборщику мусора удалять свои элементы. Все ограничения, накладываемые на WeakMap
, так же справедливы и для WeakSet
. Можно добавлять элементы в WeakSet
, проверять их наличие, но нельзя получить их список и даже узнать количество.
Example: class Foo
can ensure that its methods are only applied to instances that were created by it:
const foos = new WeakSet();
class Foo {
constructor() {
foos.add(this);
}
method() {
if (!foos.has(this)) {
throw new TypeError("Incompatible object!");
}
}
}
Last updated
Was this helpful?