Какая разница между Map и WeakMap?

👨‍💻 Frontend Developer 🟠 Может встретиться 🎚️ Средний
#JavaScript #Коллекции #База JS

Краткий ответ

Map и WeakMap — это оба коллекции типа “ключ-значение”, но у них есть важные отличия:

  1. Map может использовать любые значения как ключи, а WeakMap только объекты 🗝️
  2. Map можно перебирать, а WeakMap нельзя 🔍
  3. WeakMap автоматически удаляет пары, когда объект-ключ больше нигде не используется 🗑️
// Map — любые ключи
const map = new Map([[1, 'число'], ['a', 'строка'], [{}, 'объект']]);
 
// WeakMap — только объекты как ключи
const obj = {};
const weakMap = new WeakMap([[obj, 'значение']]);

Полный ответ

Представь, что Map — это обычная коробка с ящичками, где в каждом ящичке есть этикетка с любым названием. А WeakMap — это магическая коробка, которая сама выбрасывает ящички, когда их этикетки никто больше не помнит! 📦✨

Основные отличия

Типы ключей

// Map может использовать любые ключи
const map = new Map();
map.set(1, 'число');     // число ✅
map.set('a', 'строка');  // строка ✅
map.set({}, 'объект');   // объект ✅
 
// WeakMap только объекты как ключи
const weakMap = new WeakMap();
const keyObj = {};
// weakMap.set('строка', 'значение'); // ❌ Ошибка!
weakMap.set(keyObj, 'значение');      // ✅ Только объекты

Перебор элементов

const map = new Map([['a', 1], ['b', 2]]);
 
// Map можно перебирать
for (const [key, value] of map) {
  console.log(key, value); // 'a' 1, 'b' 2
}
 
const weakMap = new WeakMap([[{}, 'значение']]);
 
// ❌ WeakMap нельзя перебирать!
// for (const [key, value] of weakMap) // Ошибка!

Как работает WeakMap

WeakMap — как секретный сейф, который сам уничтожает документы, когда их владелец забыл о них. Если никто больше не держит на объект-ключ ссылку, WeakMap сам забудет о паре “ключ-значение”! 🔐

Автоматическая очистка

let obj = { id: 1 };
const weakMap = new WeakMap([[obj, 'приватные данные']]);
 
// Когда obj больше никем не используется
obj = null;
 
// Пара автоматически удалится из WeakMap
// Сборщик мусора позаботится об этом 🗑️

Когда использовать Map

Для хранения любых пар “ключ-значение”

// Кэширование результатов
const cache = new Map();
 
function getData(key) {
  if (cache.has(key)) {
    return cache.get(key);
  }
  
  const result = fetchData(key);
  cache.set(key, result);
  return result;
}

Когда нужен перебор

// Нужно пройтись по всем парам
const config = new Map([['theme', 'dark'], ['lang', 'ru']]);
 
config.forEach((value, key) => {
  console.log(`${key}: ${value}`);
});

Когда использовать WeakMap

Для приватных данных

// Приватные данные пользователей
const privateData = new WeakMap();
 
class User {
  constructor(name) {
    this.name = name;
    // Приватные данные не видны снаружи
    privateData.set(this, { password: 'секрет' });
  }
  
  getPassword() {
    return privateData.get(this).password;
  }
}

Для кэширования с автоматической очисткой

// Кэш, который сам очищается
const cache = new WeakMap();
 
function process(obj) {
  if (cache.has(obj)) {
    return cache.get(obj); // из кэша
  }
  
  const result = heavyCalculation(obj);
  cache.set(obj, result); // в кэш
  return result;
}
 
// Когда объект obj больше не нужен,
// кэш автоматически очистится

Частые ошибки

Попытка использовать примитивы как ключи в WeakMap

// ❌ Ошибка!
const weakMap = new WeakMap();
// weakMap.set('ключ', 'значение'); // TypeError!
// weakMap.set(123, 'значение');    // TypeError!
 
// ✅ Правильно
const obj = {};
weakMap.set(obj, 'значение'); // Только объекты как ключи!

Ожидание перебора WeakMap

// ❌ Нельзя перебирать WeakMap
const weakMap = new WeakMap([[{}, 'значение']]);
// weakMap.forEach((value, key) => {}); // Ошибка!

Простые правила

  1. Map — универсальная коробка с любыми ключами 📦
  2. WeakMap — магическая коробка только с объектами как ключами 🧙
  3. Map можно перебирать, WeakMap — нельзя 🔍
  4. WeakMap сам очищается, Map — нет 🗑️
  5. Используй Map для общих задач, WeakMap для приватных данных 🎯

Понимание разницы между Map и WeakMap помогает выбрать правильный инструмент для решения задачи и избежать проблем с памятью! 💪


Хотите больше статей для подготовки к собеседованиям? Подписывайтесь на EasyAdvice, добавляйте сайт в закладки и совершенствуйтесь каждый день 💪