Skip to main content

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.
  • Типове застосування: позначки «уже оброблено», тимчасовий кеш, приватні дані.

Швидкий приклад

javascript
const ws = new WeakSet(); const obj1 = { name: 'Alice' }; const obj2 = { name: 'Bob' }; ws.add(obj1); ws.add(obj2); console.log(ws.has(obj1)); // true

Що тут важливо:

  • Колекція зберігає тільки об'єкти, не примітиви. Спроба додати рядок або число одразу закінчиться помилкою.

    javascript
    ws.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

ВластивістьSetWeakSet
Можна зберігати примітивиТакНі, тільки об'єкти
Елементи слабко зв'язані (GC може видалити)НіТак
Можна перебрати (for...of, size)ТакНі
Використовується для тимчасових посиланьРідкоЧасто

Автоматичне видалення з пам'яті

javascript
let obj = { id: 1 }; const ws = new WeakSet(); ws.add(obj); console.log(ws.has(obj)); // true obj = null; // тепер об'єкт більше не досяжний // об'єкт автоматично буде видалений з пам'яті збирачем сміття

Як це працює:

  • Після obj = null об'єкт стає досяжним лише з WeakSet, а таке посилання не рахується «сильним», тому GC може видалити його.
  • Саме це робить WeakSet зручним для зберігання тимчасових або закешованих об'єктів: не треба вручну стежити за очищенням.

Практичний приклад: відстеження оброблених об'єктів

javascript
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.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.