JS: Коллекции
Теория: Map
В этом уроке мы познакомимся с ассоциативным массивом, а также разберем его преимущества и недостатки. Еще научимся работать с ним в языке JavaScript.
Map как объект
Ассоциативный массив — это абстрактный тип данных, который позволяет хранить пары вида «ключ, значения». Он поддерживает операции добавления пары, а также поиска и удаления по ключу.
Вспомним JavaScript-объект:
В нем много общего с ассоциативными массивами. Объект часто используется как ассоциативный массив — мы обращаемся к его значениям, которые установлены внутри по ключу. Обращение идет как через точку, так и через квадратные скобки.
Преимущества
Использование квадратных скобок дает несколько преимуществ:
- Динамическое обращение
- Динамическое обновление
- Итерация
Разберем их подробнее.
Динамическое обращение
Мы можем динамически обращаться к свойствам или ключам через переменную, в которой хранится имя ключа, вместо обращения к свойству через точку. Например:
Внутри квадратных скобок конструкция [key] ожидает выражение. Это может быть что угодно, например, мы передаем константу key, которая внутри содержит строку. Так мы получаем доступ к внутреннему значению.
Это может происходить в циклических конструкциях, где мы не знаем, с каким ключом работаем на каждой итерации.
Динамическое обновление
Так же как и с динамическим обращением вместо обновления свойства через точку мы можем делать то же самое через квадратные скобки:
В этом случае синтаксис практически не меняется.
Мы используем внутри не литерал, а переменную. Она в себе содержит имя, к свойству которого мы обращаемся.
Итерация
Для итерации по свойствам объекта в JavaScript есть методы, которые находятся не внутри самого объекта.
Чтобы итерировать, мы можем воспользоваться конструктором Object и вызвать у него метод keys, который возвращает нам ключи переданного объекта:
На выходе конструкции Object.keys(person) у нас получается массив.
Мы можем использовать любую функцию высшего порядка. Например, мы используем forEach, которая проходит по-элементно и рассчитывает, что мы внутри выполним какое-то действие.
Например, распечатываем все значения. Мы обращаемся к нашему объекту, в квадратных скобках указываем propName — переменная, содержащая ключ, который был извлечен из person. Как раз здесь проявляется динамическая природа квадратных скобок и ее удобства. Через точку у нас бы не получилось так сделать.
Есть и другой способ:
Если нам нужны не ключи, а значения, то мы можем вызвать метод Object.values() и получить сразу список значений из объекта.
Недостатки
У объектов, как и у ассоциативных массивов, есть определенные недостатки, часть из которых довольно критические:
- Дополнительные свойства
- Ключи только строки и символы
- Определение размера
Разберем их подробнее.
Дополнительные свойства
Когда мы ставим Object, у него есть большое количество свойств, которые даются ему по наследству. Эти свойства в большинстве случаев являются функциями:
Например, есть функция valueOf(). При работе со свойствами, особенно в динамическом режиме, мы можем случайно заменить ее. В итоге это приведет к определенным проблемам. Это довольно критическая вещь для определенных типов программ.
Ключи только строки и символы
Допустим, мы создали такой объект и распечатали его:
В итоге тройка превратилась в строку. То есть внутри произошло преобразование. В работе это может быть неудобно.
Определение размера
Object не дает определить размер. Поэтому можно сделать так:
Мы обращаемся черезObject.keys(), достаем все ключи и вычисляем длину. Это не очень удобный способ вычислять размер объекта.
JavaScript дает возможность работать с нормальным мапом, который уже является ассоциативным массивом. При этом у него нет тех недостатков, о которых мы говорили.
Тип Map
Map — это отдельный тип. Если сделать на нем new без переданных аргументов, то можно получить объект, с которым можно дальше работать:
При этом мы можем передать аргумент, который внутри станет ключевым значением:
Это массив массива, в котором каждый массив — это элемент из двух пар: ключ и значение. Внутри он превращается в [key, value]. Как там все хранится? мы не знаем, но у нас есть интерфейс, которым достаточно просто пользоваться.
Установка нового значения происходит через set:
Этот простой интерфейс позволяет работать и не переживать о перечисленных недостатках.
Map как коллекция
Если мы хотим работать с Map как с коллекцией, то для этого он дает из коробки несколько методов:
entries() — это новый метод, который возвращает ту структуру, которая ожидается на вход в конструктор.
Еще у Map есть свойство forEach:
Нам не нужно получать key, value и как-то его обходить. Мы
просто передаем в forEach функцию, которая принимает key, value. Это достаточно удобно для большинства моментов, где нам нужно обрабатывать Map.
Выводы
В этом уроке мы познакомились с ассоциативным массивом, а также разобрали его преимущества и недостатки. К первым относятся динамическое обращение и обновление и итерация, ко вторым — дополнительные свойства, ключи как строки и символы и определение размера.
Еще мы научились создавать объект типа Map, а также работать с ним как с коллекциями. Для последнего можно использовать методы keys, values и entries.
