Map, Set, WeakMap, WeakSet
↑ 2.1 JavaScript: продвинутый · ← Предыдущая · → Следующая
Зачем это на собесе
Когда
Mapлучше объекта и зачем нужны слабые ссылки.
Объяснение
| Структура | Особенности |
|---|---|
Map | ключи любых типов, сохраняет порядок вставки, size, итерация, быстрая частая вставка/удаление |
Set | уникальные значения, has O(1) |
WeakMap | ключи — только объекты, слабые ссылки (не мешают GC), не итерируется, нет size |
WeakSet | множество объектов со слабыми ссылками |
Object | ключи — строки/символы, прототипные ключи, порядок сложнее |
const m = new Map("a", 1);
m.set({ id: 1 }, "obj").get("a"); m.has("a"); m.delete("a"); [...m.entries()];
const s = new Set([1, 2, 2, 3]); s.add(4).has(2);
const union = new Set([...a, ...b]); // + Set.union/intersection/difference (новые версии)
// WeakMap: приватные данные и кэш без утечек
const cache = new WeakMap();
function compute(obj) { if (!cache.has(obj)) cache.set(obj, heavy(obj)); return cache.get(obj); } // запись исчезнет вместе с obj
const seen = new WeakSet(); // отметки «уже обработан» для DOM-узловКогда Map вместо {}: ключи не строки (объекты, числа), частые добавления/удаления, нужен размер и порядок, нет риска конфликта с прототипом. Когда Object: фиксированная структура, JSON.
Map не сериализуется JSON.stringify напрямую (Object.fromEntries(map)).
Нюансы и подводные камни
- Ключи
Mapсравниваются по SameValueZero (NaNравенNaN), объекты — по ссылке. - Во Vue
reactive(new Map())поддерживается, ноWeakMapне итерируется. WeakMapключ — только объект (или незарегистрированный символ).- Порядок итерации
Map— по вставке. Setсравнивает объекты по ссылке — дубликаты «равных» объектов не удаляются.
Практика
- Реализуйте LRU-кэш на
Map. - Сохраните метаданные DOM-узлов в
WeakMapи проверьте отсутствие утечки. - Посчитайте частоты слов через
Map.
Вопросы с ответами
Чем Map отличается от Object?
Ключи любого типа, порядок вставки,
size, нет унаследованных ключей.
Зачем WeakMap?
Хранить данные, связанные с объектом, не удерживая его в памяти.