03. Weak Collections
Коллекции со слабыми ссылками (weak references) отличаются стратегией хранения объектов: если некий объект присутствует только в коллекции со слабыми ссылками, то сборщику мусора разрешается очищать из памяти данный объект. Ключами таких коллекций обязаны быть объекты, а значениями -- произвольные значения.
Классы WeakSet/WeakMap полезны для ситуаций в которых вы ассоциируете данные с объектами, чей жизненный цикл вы не собираетесь контролировать:
Кэширование промежуточных результатов
Сохранение временных приватных данных
WeakMap
WeakMapWeakMap - это карта со слабыми ключами. 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
WeakSetWeakSet — особый вид 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?