// Создание пустого объекта
const map = new Map();
При этом сам map
является обычным объектом:
map instanceof Object // true
map instanceof Map // true
Но пользоваться им как обычным объектом категорически нельзя, последствия непредсказуемы, и вы точно получите не то, что ожидаете. Ниже будут описаны функции, которые вам понадобятся при работе с Map, все манипуляции должны происходить именно с ними.
Иногда бывает нужно создать Map для уже существующих данных. Такой способ работы также предусмотрен через конструктор. Правда в этом случае придется подготовить данные определенным способом:
const map = new Map([['key', 'value'], ['anotherKey', 'anotherValue']]);
К ним относятся get
, set
и has
.
has
нужен для проверки наличия ключа:
const map = new Map()
map.set('key', 'value');
map.get('key'); // value
map.has('key'); // true
// Если ключа нет, то вернется undefined
map.get('unknown'); // undefined
map.has('unknown'); // false
Map поддерживает fluent интерфейс. Функция set
возвращает сам Map. Таким образом можно строить цепочки:
const map = new Map();
map.set('key', 'value').set('anotherKey', 'anotherValue');
Подробнее про fluent интерфейс расскажем чуть позже в отдельном уроке курса.
Для удаления из Map служит функция delete
, которая принимает на вход имя ключа. Функция clear
поступает более радикально: удаляет все элементы из Map-объекта. Крайне не рекомендую строить свои алгоритмы таким образом, чтобы пришлось изменять объекты удалением ключей. Такой код сложен в отладке и понимании.
Ещё из полезных функций есть keys
и values
. Они возвращают специальный объект-итератор, чем-то отдалённо похожий на массив ключей или значений. Для возможности применить функции высшего порядка, такие как filter/reduce/map, всё же придётся производить непосредственное преобразование к массиву: Array.from(map)
.
Более подробно об итераторах мы будем говорить в одном из будущих курсов. А сейчас просто рассмотрим их применение. Они используются для перебора ключей/значений/записей Map-объекта с помощью цикла for...of.
Разберём как это работает на примере сконструированного Map-объекта person
:
const person = new Map([['name', 'John'], ['surname', 'Doe'], ['age', 50]]);
Давайте посмотрим какие вообще есть свойства у person
:
// создание итератора по ключам
// имя константы может быть любым, мы выбрали 'keys'
const keys = person.keys();
// перебор ключей
for (const key of keys) {
console.log(key);
}
// name
// surname
// age
Теперь пробежимся по значениям Map-объекта person
:
// создание итератора по значениям
const values = person.values();
// перебор значений
for (const value of values) {
console.log(value);
}
// John
// Doe
// 50
Можно перебирать сразу целые записи, то есть пары "ключ-значение":
// создание итератора по записям
const entries = person.entries();
// перебор записей
for (const entry of entries) {
console.log(entry);
}
// [ 'name', 'John' ]
// [ 'surname', 'Doe' ]
// [ 'age', 50 ]
Как видно, при переборе записей в элемент entry
на каждой итерации цикла записывается массив, содержащий пару — ключ и значение очередной записи.
У Map-объектов также есть метод forEach, который позволяет удобно сделать перебор ключей и значений. Этот метод вызывается на объекте и принимает на вход callback-функцию. На каждой итерации эта callback-функция принимает ключ и значение очередной записи объекта, поэтому надо предусмотреть для них в сигнатуре функции соответствующие параметры (в примере ниже, это параметры value
и key
):
const person = new Map([['name', 'John'], ['surname', 'Doe'], ['age', 50]]);
// подготавливаем callback-функцию
const cb = (value, key) => console.log(`${key} - ${value}`);
// делаем обход Map-объекта
person.forEach(cb);
// name - John
// surname - Doe
// age - 50
Обратите внимание, что при итерировании Map-объектов происходит перебор свойств в порядке их добавления. Обычный объект типа object
гарантирует порядок, при котором сначала идут числа по возрастанию, потом строки в порядке добавления, а затем символы тоже в порядке добавления.
Может возникнуть вопрос, зачем нужен Map если есть объект? И, в реальности, действительно так. Map используется редко. Основная причина его использования в JS заключается в том, что обычный объект имеет множество служебных свойств, которые содержат важную информацию и функции. Если эти функции случайно перезапишут, то программа может просто сломаться. Например:
const obj = {};
console.log(`${obj}`); // => [object Object]
// Метод toString() срабатывает, когда сущность приводится к строке
// Перезаписываем (случайно или специально)
obj['toString'] = 'value';
console.log(`${obj}`); // => TypeError: Cannot convert object to primitive value
С Map такое не пройдет. Все свойства записывающиеся через set
попадают в такую область, где ничего нельзя сломать. Другими словами, Map полезен тогда, когда нет контроля над свойствами, то есть когда они могут динамически заполняться пользовательскими данными.
const map = new Map();
console.log(`${map}`); // => [object Map]
map.set('toString', 'value');
console.log(`${map}`); // => [object Map]
Из того, что Map хранит свойства особым образом, следует то, что им нельзя пользоваться как обычным объектом (технически конечно можно, но тогда непонятно зачем используется Map). Например установленные свойства через set
невозможно получить прямым доступом к свойствам объекта. Точно такая же ситуация и при чтении. Установленное через обычные свойства нельзя получить через get
.
const map = new Map();
map['key'] = 'value';
map.get('key'); // undefined
map.set('key2', 'value2');
map['key2']; // undefined
Вам ответят команда поддержки Хекслета или другие студенты.
Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.
Загляните в раздел «Обсуждение»:
Статья «Ловушки обучения»
Вебинар «Как самостоятельно учиться»
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.
Наши выпускники работают в компаниях:
Зарегистрируйтесь или войдите в свой аккаунт