Что такое Map и Set в JavaScript?
Map
Map — это структура данных, хранящая пары «ключ–значение», аналогично обычному объекту. Ключевое отличие: ключами могут быть любые значения — объекты, функции, примитивы. Объект же приводит ключи к строкам.
Основные методы Map
map.set(key, value)— устанавливает значениеmap.get(key)— возвращает значение по ключуmap.has(key)— проверяет наличие ключаmap.delete(key)— удаляет элементmap.size— количество элементовmap.clear()— очищает коллекциюmap.keys(),map.values(),map.entries()— итераторы
Map сохраняет порядок вставки — при итерации элементы идут именно в том порядке, в котором добавлялись.
Когда использовать Map вместо Object
Map предпочтительнее объекта, когда ключи могут быть не строками, когда важна производительность при частых добавлениях/удалениях, или когда нужно отслеживать количество элементов через size.
Set
Set — коллекция уникальных значений любого типа. Попытка добавить уже существующее значение игнорируется. Порядок вставки также сохраняется.
Основные методы Set
set.add(value)— добавляет значениеset.has(value)— проверяет наличиеset.delete(value)— удаляет значениеset.size— количество элементовset.clear()— очищает коллекциюset.forEach(),set.values(),set.entries()— итерация
Сравнение с Array
Set эффективнее массива при проверке наличия элемента — операция has() работает за O(1) против O(n) у Array.includes(). Классическое применение Set — дедупликация массива: [...new Set(array)].
WeakMap и WeakSet
Существуют «слабые» версии: WeakMap и WeakSet. В них ключи (WeakMap) или значения (WeakSet) хранятся как слабые ссылки — если объект больше нигде не используется, сборщик мусора может его удалить. Они не итерируемы и не имеют свойства size. Применяются для кэширования данных, связанных с объектами, без риска утечек памяти.
Что хочет услышать интервьюер
Кандидат чётко объясняет разницу между Map/Object и Set/Array
Упоминает, что ключи Map могут быть любого типа (не только строки)
Знает про сохранение порядка вставки и свойство size
Называет практические сценарии: дедупликация через Set, Map как словарь с нестроковыми ключами
Хорошим бонусом будет упоминание WeakMap/WeakSet и их роли в управлении памятью
Пример: Map: ключи любого типа
const map = new Map<object | string, number>();
const objKey = { id: 1 };
// Объект как ключ — невозможно с обычным Object
map.set(objKey, 42);
map.set('строка', 10);
console.log(map.get(objKey)); // 42
console.log(map.size); // 2
// Итерация по Map
for (const [key, value] of map) {
console.log(key, value);
}
// Преобразование в массив
const entries = [...map.entries()];
Пример: Set: уникальные значения и дедупликация
const set = new Set<number>([1, 2, 2, 3, 3, 3]);
console.log(set.size); // 3 — дубликаты удалены
console.log(set.has(2)); // true
set.add(4);
set.delete(1);
console.log([...set]); // [2, 3, 4]
// Классический паттерн: дедупликация массива
const arr = [1, 1, 2, 3, 3, 4];
const unique = [...new Set(arr)];
console.log(unique); // [1, 2, 3, 4]
// Пересечение двух множеств
const a = new Set([1, 2, 3]);
const b = new Set([2, 3, 4]);
const intersection = new Set([...a].filter(x => b.has(x)));
console.log([...intersection]); // [2, 3]
Пример: WeakMap: кэш без утечек памяти
const cache = new WeakMap<object, string>();
function processUser(user: object): string {
if (cache.has(user)) {
return cache.get(user)!; // берём из кэша
}
const result = JSON.stringify(user); // тяжёлая операция
cache.set(user, result); // сохраняем результат
return result;
}
let user = { name: 'Иван' };
processUser(user);
// Когда user = null, сборщик мусора автоматически
// очистит запись в WeakMap — утечки памяти не будет
user = null as any;
Типичные ошибки
Путают Map с обычным объектом, не объясняя принципиальное отличие по типу ключей
Забывают про свойство size и пытаются использовать length
Не знают об итераторах map.keys(), map.values(), map.entries()
Не могут назвать реальный сценарий применения — используют Map там, где достаточно объекта, и наоборот
Игнорируют WeakMap/WeakSet, хотя на middle-уровне их понимание ожидаемо


