Ответ
Map — это встроенная в JavaScript коллекция для хранения пар ключ-значение, где ключом может быть значение любого типа (объект, функция, примитив), в отличие от обычных объектов, где ключи автоматически преобразуются в строки.
Зачем использовать Map в Node.js?
- Ключи любого типа: Идеально для сопоставления объектов метаданных или DOM-элементов (в SSR) со значениями.
- Сохранение порядка вставки: При итерации элементы возвращаются в порядке их добавления.
- Удобный API: Имеет методы
get,set,has,deleteи свойствоsize. - Производительность: В сценариях частого добавления/удаления пар
Mapможет быть быстрее объекта.
Базовый пример:
// Создание и использование Map
const userSessions = new Map();
// Ключом может быть объект (например, WebSocket соединение)
const socket = { id: 'ws-123' };
const user = { id: 'user-456', name: 'Alice' };
userSessions.set(socket, user); // Ключ - объект
userSessions.set(user.id, socket); // Ключ - строка
console.log(userSessions.get(socket)); // { id: 'user-456', name: 'Alice' }
console.log(userSessions.has(user.id)); // true
console.log(userSessions.size); // 2
// Итерация (порядок сохранён)
for (const [key, value] of userSessions) {
console.log(key, '->', value);
}
// Вывод:
// { id: 'ws-123' } -> { id: 'user-456', name: 'Alice' }
// 'user-456' -> { id: 'ws-123' }
// Удаление
userSessions.delete(user.id);
Практический пример в Node.js: простой in-memory кэш с TTL (Time To Live):
class SimpleCache {
constructor() {
this.cache = new Map(); // Хранит данные: ключ -> { value, expiry }
}
set(key, value, ttlMs = 5000) {
const expiry = Date.now() + ttlMs;
this.cache.set(key, { value, expiry });
// Автоочистка просроченных записей (можно вынести в отдельный интервал)
setTimeout(() => {
if (this.cache.get(key)?.expiry < Date.now()) {
this.cache.delete(key);
}
}, ttlMs);
}
get(key) {
const item = this.cache.get(key);
if (!item) return null;
if (item.expiry < Date.now()) {
this.cache.delete(key);
return null;
}
return item.value;
}
}
// Использование
const cache = new SimpleCache();
cache.set('api_response_123', { data: 'someData' }, 10000);
console.log(cache.get('api_response_123')); // { data: 'someData' }
setTimeout(() => {
console.log(cache.get('api_response_123')); // null (после истечения TTL)
}, 11000);
| Map vs Object: | Критерий | Map |
Object |
|---|---|---|---|
| Ключи | Любого типа | Только String или Symbol | |
| Порядок | Сохраняет порядок вставки | Не гарантирован (хотя в современных JS есть порядок для строковых ключей) | |
| Размер | map.size |
Object.keys(obj).length |
|
| Итерация | Прямо итерируем (for...of) |
Требуется Object.keys, for...in |
|
| Прототип | Не имеет унаследованных ключей | Может иметь ключи из цепочки прототипов | |
| Производительность | Лучше при частых добавлениях/удалениях | Лучше в сценариях статической структуры |
Ответ 18+ 🔞
Слушай, я тут подумал — сколько же народу до сих пор тупо юзает обычные объекты для всего подряд, а про Map нихуя не знает или знает, но лень. Это ж, бля, просто ёперный театр какой-то!
Вот смотри, Map — это такая встроенная в JS штука, которая хранит пары «ключ — значение». И главный её прикол, от которого сам от себя охуеешь, — ключом может быть что угодно: объект, функция, хоть твой левый тапочек. Не то что у объектов, где все ключи автоматом в строку превращаются, хоть ты тресни.
Ну и нахуя он нужен в Node.js, спросишь?
- Ключи любого типа: Идеально, когда надо привязать какие-то метаданны к объекту или, там, DOM-элементу (если на SSR городишь). Никаких костылей.
- Порядок вставки помнит: Когда перебираешь, всё идёт ровно в том порядке, в каком ты это запихал. У обычного объекта с этим, бля, волнение ебать — как карта ляжет.
- Удобный API: Есть нормальные методы
get,set,has,deleteи свойствоsize. Никаких этихObject.keys(obj).length— терпения ноль ебать на это. - Бывает быстрее: Если ты постоянно что-то добавляешь и удаляешь,
Mapможет оказаться шустрее объекта. Хуй с горы, но факт.
Смотри, как просто:
// Создаём и юзаем Map
const userSessions = new Map();
// Ключом может быть объект (ну, типа, WebSocket-соединение)
const socket = { id: 'ws-123' };
const user = { id: 'user-456', name: 'Alice' };
userSessions.set(socket, user); // Ключ — объект, ёпта!
userSessions.set(user.id, socket); // А тут ключ — строка
console.log(userSessions.get(socket)); // { id: 'user-456', name: 'Alice' }
console.log(userSessions.has(user.id)); // true
console.log(userSessions.size); // 2
// Перебор (всё в порядке добавления)
for (const [key, value] of userSessions) {
console.log(key, '->', value);
}
// Выведет:
// { id: 'ws-123' } -> { id: 'user-456', name: 'Alice' }
// 'user-456' -> { id: 'ws-123' }
// Удаление — раз плюнуть
userSessions.delete(user.id);
А вот практический пример: простой кэш в памяти с TTL (время жизни):
class SimpleCache {
constructor() {
this.cache = new Map(); // Храним: ключ -> { value, expiry }
}
set(key, value, ttlMs = 5000) {
const expiry = Date.now() + ttlMs;
this.cache.set(key, { value, expiry });
// Можно поставить автоочистку просрочки (или в отдельный интервал вынести)
setTimeout(() => {
if (this.cache.get(key)?.expiry < Date.now()) {
this.cache.delete(key);
}
}, ttlMs);
}
get(key) {
const item = this.cache.get(key);
if (!item) return null;
if (item.expiry < Date.now()) {
this.cache.delete(key); // Просрочился — нахуй
return null;
}
return item.value;
}
}
// Используем
const cache = new SimpleCache();
cache.set('api_response_123', { data: 'someData' }, 10000);
console.log(cache.get('api_response_123')); // { data: 'someData' }
setTimeout(() => {
console.log(cache.get('api_response_123')); // null (протухло)
}, 11000);
И главное — Map vs обычный Object, чтобы ты понимал, где что применять:
| Критерий | Map |
Object |
|---|---|---|
| Ключи | Что угодно, хоть манда с ушами | Только строка или символ |
| Порядок | Чётко помнит, кто за кем зашёл | Гарантий нет, хотя в современных движках для строковых ключей порядок есть |
| Размер | map.size — раз, и готово |
Object.keys(obj).length — ещё посчитай |
| Итерация | Прямо for...of |
Надо Object.keys или for...in |
| Прототип | Чистый, унаследованного говна нет | Может быть засран ключами из цепочки прототипов |
| Скорость | Часто быстрее, когда ключей овердохуища и их постоянно меняют | Быстрее, если структура статичная и известная |
Короче, чувак, если тебе нужно гибко ассоциировать данные — бери Map и не еби мозг. А если структура простая и известная заранее — объект сойдёт. Главное — понимать разницу, а не тыкать наугад.
Видео-ответы
▶
▶
▶
▶
▶
▶
▶