Map в JavaScript
Map - это коллекция для хранения данных в формате ключ - значение. По смыслу она похожа на объект, но лучше подходит для случаев, когда ключи заранее неизвестны, часто добавляются или могут быть не только строками.
В Map можно хранить настройки, роли пользователей, результаты поиска, связи между объектами и другие данные, где важно быстро получить значение по ключу.
Как создать Map
let userRoles = new Map()
После создания коллекция будет пустой. Добавить данные можно с помощью метода set().
let userRoles = new Map()
userRoles.set('admin', 'full access')
userRoles.set('editor', 'can edit')
В первом аргументе указывается ключ, во втором - значение, которое нужно сохранить.
Map также можно создать сразу с начальными данными. Для этого передается массив, где каждый элемент - это пара [key, value].
let userRoles = new Map([
['admin', 'full access'],
['editor', 'can edit'],
['guest', 'read only'],
])
Получение данных из Map
Чтобы получить значение по ключу, используется метод get().
let userRoles = new Map([
['admin', 'full access'],
['editor', 'can edit'],
])
userRoles.get('admin') // 'full access'
Если такого ключа нет, метод вернет undefined.
userRoles.get('guest') // undefined
Проверить наличие ключа можно с помощью метода has().
userRoles.has('editor') // true
userRoles.has('guest') // false
Если значение может быть undefined, лучше проверять ключ через has(), а не только смотреть на результат get().
Методы для работы с Map
set()
Добавляет новую пару ключ - значение или обновляет значение, если такой ключ уже есть.
let settings = new Map()
settings.set('theme', 'dark')
settings.set('theme', 'light')
settings.get('theme') // 'light'
delete()
Удаляет элемент по ключу и возвращает true, если элемент был найден.
let settings = new Map([
['theme', 'dark'],
['language', 'ru'],
])
settings.delete('theme') // true
settings.has('theme') // false
clear()
Удаляет все элементы из коллекции.
settings.clear()
settings.size // 0
size
Свойство size хранит количество элементов в Map.
let settings = new Map([
['theme', 'dark'],
['language', 'ru'],
])
settings.size // 2
Ключи в Map
В обычном объекте имена свойств чаще всего являются строками. В Map ключом может быть строка, число, объект, массив, функция или другое значение.
let user = { name: 'Alex' }
let visits = new Map()
visits.set(user, 5)
visits.get(user) // 5
С объектами важно учитывать ссылку. Если создать другой объект с такими же свойствами, для Map это будет уже другой ключ.
let firstUser = { name: 'Alex' }
let secondUser = { name: 'Alex' }
let visits = new Map()
visits.set(firstUser, 5)
visits.get(secondUser) // undefined
Перебор Map
Map хранит элементы в порядке их добавления. Перебрать коллекцию можно циклом for…of.
let userRoles = new Map([
['admin', 'full access'],
['editor', 'can edit'],
['guest', 'read only'],
])
for (let [role, access] of userRoles) {
console.log(role, access)
}
Также можно отдельно получить ключи, значения или пары ключ-значение.
keys()- возвращает ключи;values()- возвращает значения;entries()- возвращает пары[key, value].
Эти методы возвращают перебираемые объекты. Если нужен обычный массив, можно использовать Array.from().
Array.from(userRoles.keys()) // ['admin', 'editor', 'guest']
Array.from(userRoles.values()) // ['full access', 'can edit', 'read only']
Array.from(userRoles.entries()) // [['admin', 'full access'], ...]
Метод forEach() тоже работает с Map.
userRoles.forEach((access, role) => {
console.log(`${role}: ${access}`)
})
В forEach() первым параметром приходит значение, вторым - ключ.
Map и обычный объект
Обычный объект удобно использовать, когда мы описываем сущность с понятными свойствами: пользователя, товар, настройки страницы.
let user = {
name: 'Alex',
age: 25,
city: 'Moscow',
}
Map удобнее, когда данные больше похожи на коллекцию: их нужно часто добавлять, удалять, перебирать и получать по ключу.
let cart = new Map()
cart.set('book', 2)
cart.set('pen', 5)
cart.get('book') // 2
Map и array.map()
Map и array.map() - это разные вещи. Map является коллекцией данных, а array.map() - методом массива, который создает новый массив на основе старого.
let prices = [100, 200, 300]
prices.map(price => price * 2) // [200, 400, 600]
Если нужно преобразовать массив, используется map(). Если нужно хранить пары ключ - значение, используется Map.
Итого
Map - это удобная коллекция для данных, где у каждого значения есть свой ключ. Она сохраняет порядок добавления, умеет быстро проверять наличие ключа, легко перебирается и позволяет использовать в качестве ключей не только строки.