Skip to main content

Колекція Map у JavaScript

Map це вбудований об'єкт JavaScript, який зберігає пари «ключ, значення» і запам'ятовує порядок вставки цих пар. Він схожий на звичайний об'єкт {}, але має розширені можливості: ключем може бути будь-який тип даних, є зручні методи для додавання, видалення та перебору, і порядок елементів гарантований.

Теорія

TL;DR

  • Map це колекція пар «ключ, значення» з гарантованим порядком вставки.
  • Ключем може бути будь-що: рядок, число, об'єкт, функція, навіть NaN.
  • Ключі-об'єкти порівнюються за посиланням, а не за рядковим представленням.
  • Методи: set, get, has, delete, clear, плюс властивість size.
  • Колекція ітерована: for...of, .forEach(), .keys(), .values(), .entries().
  • Конвертація в обидва боки: new Map(Object.entries(obj)) і Object.fromEntries(map).

Швидкий приклад

javascript
const map = new Map(); map.set('name', 'Alex'); map.set('age', 25); console.log(map.get('name')); // Alex console.log(map.get('age')); // 25 console.log(map.size); // 2

Основні методи та властивості

Метод / властивістьЩо робитьПриклад
set(key, value)Додає елементmap.set('a', 1)
get(key)Повертає значення за ключемmap.get('a')
has(key)Перевіряє наявність ключаmap.has('a') // true
delete(key)Видаляє елементmap.delete('a')
clear()Очищає всю колекціюmap.clear()
sizeКількість елементівmap.size // 2

set() повертає сам Map, тому виклики можна зв'язувати в ланцюжок: map.set('a', 1).set('b', 2).

Ключі будь-якого типу

javascript
const map = new Map(); const objKey = { id: 1 }; const funcKey = () => {}; const numKey = 42; map.set(objKey, 'object'); map.set(funcKey, 'function'); map.set(numKey, 'number'); console.log(map.get(objKey)); // object console.log(map.get(funcKey)); // function console.log(map.get(42)); // number

На відміну від звичайного об'єкта {}, ключі тут порівнюються за посиланням, а не за приведеною до рядка формою. Тому { id: 1 } і новий літерал { id: 1 } це два різні ключі.

Навіть NaN працює як ключ, що в звичайних об'єктах неможливо:

javascript
const map = new Map(); map.set(NaN, 'Not a Number'); console.log(map.get(NaN)); // 'Not a Number'

Перебір Map

Map це ітерована колекція, тож обійти її можна кількома способами.

  1. for...of:
javascript
const map = new Map([ ['name', 'Alex'], ['age', 25], ]); for (const [key, value] of map) { console.log(`${key}: ${value}`); } // name: Alex // age: 25
  1. Метод forEach (зверніть увагу на порядок аргументів: спочатку значення, потім ключ):
javascript
map.forEach((value, key) => { console.log(key, value); });
  1. Окремо ключі, значення або записи:
javascript
console.log([...map.keys()]); // ['name', 'age'] console.log([...map.values()]); // ['Alex', 25] console.log([...map.entries()]); // [['name','Alex'], ['age',25]]

Map проти звичайного об'єкта

ОсобливістьObjectMap
Тип ключівТільки рядок або символБудь-який тип, включно з об'єктами та функціями
Порядок елементівНе гарантований (до ES2015)Гарантований
Кількість елементівТреба рахувати вручну (Object.keys().length)map.size
Видаленняdelete obj.key (повільно)map.delete(key) (швидко)
Перебірfor...in (разом з успадкованими властивостями)Чистий for...of
ПродуктивністьКраще для невеликих наборів данихКраще для частих вставок і видалень

Конвертація та практичне застосування

З об'єкта в Map:

javascript
const obj = { a: 1, b: 2 }; const map = new Map(Object.entries(obj));

З Map в об'єкт:

javascript
const obj2 = Object.fromEntries(map);

Лічильник входжень елементів, класичний випадок для Map:

javascript
const arr = ['a', 'b', 'a', 'c', 'b', 'a']; const counter = new Map(); for (const item of arr) { counter.set(item, (counter.get(item) || 0) + 1); } console.log(counter); // Map(3) { 'a' => 3, 'b' => 2, 'c' => 1 }

Беріть Map, якщо:

  • потрібно зберігати не тільки рядки як ключі;
  • важливо зберігати порядок вставки;
  • потрібні часті додавання та видалення елементів;
  • ви працюєте з асоціативними структурами даних.

Коротке резюме:

ЩоОпис
ТипКолекція «ключ, значення»
КлючіБудь-які типи, включно з об'єктами
ПорядокЗберігається
Методи.set(), .get(), .has(), .delete(), .clear()
Розмірmap.size
Перебірfor...of, .forEach(), .keys(), .values(), .entries()

Типові помилки

  • Звертатися до Map як до об'єкта. map['name'] створить звичайну властивість на об'єкті Map, а не запис у колекції; map.get('name') поверне undefined.
  • Чекати на map.length. У Map немає length, є size, і це властивість, а не метод.
  • Використовувати новий літерал об'єкта як ключ для пошуку. map.set({ id: 1 }, x) і map.get({ id: 1 }) це різні посилання, тому результат буде undefined.
  • Плутати порядок аргументів у forEach. Колбек отримує (value, key, map), а не (key, value).
  • Серіалізувати Map через JSON.stringify. Результат буде {}; спочатку перетворіть колекцію на об'єкт або масив, наприклад Object.fromEntries(map).
  • Тримати об'єкти-ключі в Map і чекати, що їх прибере збирач сміття. Map тримає сильні посилання; для слабких потрібен WeakMap.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.