Для чего нужен Map
Map — это встроенный объект в JavaScript, предназначенный для хранения пар ключ–значение, где ключи могут быть любого типа, включая объекты, функции и примитивы. Это отличает Map от обычных объектов (Object), у которых ключи могут быть только строками или символами. Map был добавлен в язык в ECMAScript 2015 (ES6) и предоставляет более гибкий, эффективный и предсказуемый способ работы с ассоциативными коллекциями.
📌 Основные характеристики Map
-
Упорядоченность
Map сохраняет порядок добавления элементов. Это значит, что при итерации элементы возвращаются в том порядке, в каком они были добавлены. -
Любые типы ключей
В отличие от Object, где ключи автоматически приводятся к строкам, Map поддерживает любые значения в качестве ключей: объекты, функции, числа, строки и даже NaN. -
Размер
Метод map.size возвращает количество пар ключ–значение в коллекции, в отличие от объектов, где приходится использовать Object.keys(obj).length.
🔧 Основные методы и свойства Map
Метод/свойство | Описание |
---|---|
new Map() | Создаёт новый пустой Map. |
--- | --- |
set(key, value) | Добавляет пару ключ–значение в коллекцию. Возвращает сам Map для чейнинга. |
--- | --- |
get(key) | Возвращает значение по ключу. Если ключ не найден — undefined. |
--- | --- |
has(key) | Возвращает true, если ключ существует в коллекции. |
--- | --- |
delete(key) | Удаляет элемент по ключу. Возвращает true, если элемент был удалён. |
--- | --- |
clear() | Очищает весь Map. |
--- | --- |
size | Свойство, возвращающее количество пар ключ–значение. |
--- | --- |
🧠 Примеры использования
const map = new Map();
// Добавление
map.set('name', 'Alice');
map.set(42, 'answer');
map.set(true, 'yes');
// Получение
console.log(map.get('name')); // Alice
console.log(map.get(42)); // answer
console.log(map.get(true)); // yes
// Проверка наличия ключа
console.log(map.has('name')); // true
// Размер
console.log(map.size); // 3
// Удаление
map.delete(42);
// Итерация
for (let \[key, value\] of map) {
console.log(\`${key} = ${value}\`);
}
🔄 Итерация по Map
Map реализует интерфейс Iterable, поэтому можно использовать:
-
for...of
-
map.forEach()
-
Спред-оператор (...)
-
Деструктуризацию
Примеры:
for (let \[key, value\] of map) {
console.log(key, value);
}
map.forEach((value, key) => {
console.log(key, value);
});
📘 Отличия Map от Object
Характеристика | Map | Object |
---|---|---|
Ключи | Любые значения | Только строки или символы |
--- | --- | --- |
Сохранение порядка | Да | Нет (до ES2015 не гарантировалось) |
--- | --- | --- |
Производительность | Оптимизирован под частые операции | Меньше оптимизирован |
--- | --- | --- |
Итерация | Легко через for...of, forEach | Необходимость использовать for...in + hasOwnProperty |
--- | --- | --- |
Количество элементов | map.size | Object.keys(obj).length |
--- | --- | --- |
Прототипное наследование | Нет | Да (Object.prototype) |
--- | --- | --- |
🛠 Применения Map в реальных задачах
Кэширование
Используется для хранения ранее вычисленных значений, особенно при реализации мемоизации.
const cache = new Map();
function fib(n) {
if (cache.has(n)) return cache.get(n);
if (n <= 1) return n;
const result = fib(n - 1) + fib(n - 2);
cache.set(n, result);
return result;
}
Словари и соответствия
Быстрое сопоставление значений. Например, таблица перевода:
const translate = new Map([
\['hello', 'привет'\],
\['world', 'мир'\]
\]);
console.log(translate.get('hello')); // привет
Счётчики значений
Подсчёт количества повторений элементов:
const counter = new Map();
const arr = \['a', 'b', 'a', 'c', 'b', 'a'\];
arr.forEach(el => {
counter.set(el, (counter.get(el) || 0) + 1);
});
console.log(counter); // Map { 'a' => 3, 'b' => 2, 'c' => 1 }
🧩 Вложенные ключи и ключи-объекты
В Object нельзя использовать объект как ключ — он будет приведён к строке "[object Object]". В Map можно:
const objKey = { id: 1 };
const map = new Map();
map.set(objKey, 'value for object');
console.log(map.get(objKey)); // "value for object"
Это особенно важно при работе с DOM-элементами, структурами данных или уникальными объектами.
🛡 WeakMap: родственный Map
-
Хранит только объекты в качестве ключей.
-
Ключи не являются защищёнными от сбора мусора (GC).
-
Используется для приватных данных и ассоциаций.
const wm = new WeakMap();
const obj = {};
wm.set(obj, 'hidden data');
console.log(wm.get(obj)); // hidden data
Если obj удаляется и больше нигде не используется, то ключ и значение в WeakMap также удаляются автоматически.
📈 Производительность
Map реализован на хеш-таблицах, что обеспечивает:
-
O(1) время доступа по ключу (в среднем),
-
быстрый поиск, вставка, удаление,
-
предсказуемое поведение, особенно в больших коллекциях,
-
улучшенная производительность в случаях, когда часто добавляются и удаляются элементы.
Таким образом, Map — это мощный и гибкий инструмент для хранения и управления ассоциативными структурами в JavaScript, с рядом преимуществ по сравнению с обычными объектами, особенно при работе с ключами нестандартных типов и необходимостью упорядоченного доступа.