WeakSet у JavaScript
WeakSet це «полегшена» версія Set, яка зберігає тільки об'єкти і робить це слабким посиланням, тому й називається Weak. Він потрібен для ситуацій, коли треба зберігати унікальні об'єкти, але не заважати збирачу сміття (garbage collector, GC) видалити їх, якщо вони більше ніде не використовуються.
Теорія
TL;DR
WeakSetзберігає тільки об'єкти, примітиви кидаютьTypeError.- Посилання на елементи слабкі: GC може видалити об'єкт, поки той лежить у колекції.
- Доступні лише три методи:
add(value),delete(value),has(value). - Немає
size,forEach,keys,values,entries, бо колекцію не можна перебирати. - Елементи унікальні, як і в
Set. - Типове застосування: позначки «уже оброблено», тимчасовий кеш, приватні дані.
Швидкий приклад
const ws = new WeakSet();
const obj1 = { name: 'Alice' };
const obj2 = { name: 'Bob' };
ws.add(obj1);
ws.add(obj2);
console.log(ws.has(obj1)); // trueЩо тут важливо:
-
Колекція зберігає тільки об'єкти, не примітиви. Спроба додати рядок або число одразу закінчиться помилкою.
javascriptws.add(123); // TypeError: Invalid value used in weak set -
Якщо
obj1більше ніде не використовується, збирач сміття видалить його автоматично, а запис зникне зWeakSet.
Методи WeakSet
| Метод | Опис | Приклад |
|---|---|---|
add(value) | додає об'єкт | ws.add(obj) |
delete(value) | видаляє об'єкт | ws.delete(obj) |
has(value) | перевіряє наявність | ws.has(obj) |
Зверніть увагу: немає методів size, forEach, keys, values, entries, тому що WeakSet не можна перебирати. Це не забаганка специфікації: GC прибирає елементи в непередбачуваний момент, тож будь-який перебір давав би недетермінований результат.
Головна відмінність від Set
| Властивість | Set | WeakSet |
|---|---|---|
| Можна зберігати примітиви | Так | Ні, тільки об'єкти |
| Елементи слабко зв'язані (GC може видалити) | Ні | Так |
Можна перебрати (for...of, size) | Так | Ні |
| Використовується для тимчасових посилань | Рідко | Часто |
Автоматичне видалення з пам'яті
let obj = { id: 1 };
const ws = new WeakSet();
ws.add(obj);
console.log(ws.has(obj)); // true
obj = null; // тепер об'єкт більше не досяжний
// об'єкт автоматично буде видалений з пам'яті збирачем сміттяЯк це працює:
- Після
obj = nullоб'єкт стає досяжним лише зWeakSet, а таке посилання не рахується «сильним», тому GC може видалити його. - Саме це робить
WeakSetзручним для зберігання тимчасових або закешованих об'єктів: не треба вручну стежити за очищенням.
Практичний приклад: відстеження оброблених об'єктів
const processed = new WeakSet();
function process(obj) {
if (processed.has(obj)) {
console.log('Already processed');
return;
}
processed.add(obj);
console.log('Processing:', obj.name);
}
const user = { name: 'Alice' };
process(user); // Processing: Alice
process(user); // Already processed
// після user = null об'єкт автоматично зникне з WeakSetТут WeakSet виконує роль «невидимого прапорця» на об'єкті: ми не додаємо йому службове поле на кшталт obj.__processed, не забруднюємо структуру даних і не тримаємо об'єкт у пам'яті довше, ніж треба.
Коротко
| Властивість | Значення |
|---|---|
| Тип | Колекція унікальних об'єктів |
| Примітиви | Не можна |
| Збирач сміття | Може видаляти елементи |
| Перебір | Неможливий |
| Методи | add, delete, has |
| Часте застосування | Кешування, позначки «оброблено», приватні дані |
Підсумок:
WeakSetце колекція унікальних об'єктів, які автоматично видаляються з пам'яті, якщо на них більше немає інших посилань. Він чудово підходить для тимчасових позначок і кешування, і не підходить, якщо дані треба зберігати постійно або перебирати.
Типові помилки
- Намагатися додати примітив.
ws.add('text')абоws.add(5)цеTypeError, ключем може бути тільки об'єкт. - Шукати
sizeабо цикл. Дізнатися кількість елементів чи пройтися по них неможливо в принципі, для цього потрібен звичайнийSet. - Зберігати в
WeakSetдані, які мають жити довго. Якщо зовнішніх посилань немає, запис може зникнути будь-коли, це не сховище. - Вважати, що видалення відбувається миттєво. GC працює тоді, коли вважає за потрібне, тому
has()не гарантує негайногоfalseпісля скидання останнього посилання. - Плутати з
WeakMap.WeakSetзберігає самі об'єкти,WeakMapзберігає пари «об'єкт до значення». - Робити з нього кеш із результатами.
WeakSetпам'ятає лише факт наявності; щоб прив'язати до об'єкта значення, потрібенWeakMap.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.