Когда использовать массив, объект, Set или Map в JavaScript

В JavaScript одни и те же данные часто можно хранить разными способами. Например, список товаров можно записать в массив, объект, Set или Map, но удобство работы будет разным.

Главный вопрос не в том, какая структура современнее, а в том, что вы собираетесь делать с данными: хранить список, описывать объект, проверять уникальность или получать значения по ключу.

Массив

Массив подходит, когда данные идут списком и важен порядок элементов. Например, список уроков, товаров, сообщений или задач.

let lessons = ['Set', 'Map', 'WeakSet и WeakMap']

lessons.push('Массив, объект, Set или Map')

С массивом удобно использовать индексы, методы перебора и методы преобразования: map(), filter(), find(), reduce().

let prices = [100, 250, 400]

let salePrices = prices.map(price => price * 0.9)

Массив стоит выбирать, если нужно сохранить порядок, пройтись по всем элементам или получить новый массив на основе старого.

Объект

Объект подходит, когда нужно описать сущность с понятными свойствами. Например, пользователя, товар, настройки страницы или результат формы.

let user = {
  name: 'Alex',
  age: 25,
  city: 'Moscow',
}

В объекте каждое свойство имеет имя и значение. Такая запись хорошо читается, когда заранее понятно, какие данные мы храним.

let course = {
  title: 'JavaScript',
  lessonsCount: 42,
  isPublished: true,
}

Объект стоит выбирать, если данные описывают один предмет или одну сущность.

Set

Set подходит, когда нужно хранить только уникальные значения. Повторные значения в такую коллекцию не добавляются.

let tags = new Set()

tags.add('javascript')
tags.add('html')
tags.add('javascript')

tags.size // 2

С помощью Set удобно удалять дубли из массива.

let tags = ['javascript', 'html', 'javascript', 'css']
let uniqueTags = new Set(tags)

Array.from(uniqueTags) // ['javascript', 'html', 'css']

Set стоит выбирать, если важен сам факт наличия значения, а не его индекс или дополнительная информация.

Map

Map подходит, когда нужно хранить коллекцию в формате ключ - значение. По смыслу это похоже на объект, но Map удобнее, если данные часто добавляются, удаляются или ключами могут быть не только строки.

let cart = new Map()

cart.set('book', 2)
cart.set('pen', 5)

cart.get('book') // 2

В Map легко проверить наличие ключа, узнать количество элементов и перебрать коллекцию.

cart.has('pen') // true
cart.size // 2

Map стоит выбирать, если данные больше похожи на справочник или таблицу соответствий, где по ключу нужно быстро получить значение.

Пример выбора

Представим интернет-магазин. Для разных частей одной задачи могут подойти разные структуры.

Список товаров удобнее хранить в массиве.

let products = [
  { id: 1, title: 'Book', price: 500 },
  { id: 2, title: 'Pen', price: 50 },
]

Один товар удобнее описать объектом.

let product = {
  id: 1,
  title: 'Book',
  price: 500,
}

Избранные товары можно хранить в Set, потому что один товар не должен попасть туда два раза.

let favoriteIds = new Set()

favoriteIds.add(1)
favoriteIds.add(1)

favoriteIds.has(1) // true

Количество товаров в корзине можно хранить в Map, где ключом будет id товара, а значением - количество.

let cart = new Map()

cart.set(1, 2)
cart.set(2, 1)

cart.get(1) // 2

Как быстро выбрать

  • Нужен список и порядок элементов - используйте массив.
  • Нужно описать одну сущность с полями - используйте объект.
  • Нужны только уникальные значения - используйте Set.
  • Нужна коллекция пар ключ - значение - используйте Map.

Если сомневаетесь между объектом и Map, начните с объекта, когда данные имеют фиксированную структуру. Используйте Map, когда работаете именно с коллекцией записей, которую нужно часто изменять и перебирать.

Итого

Массив нужен для списков, объект - для описания сущностей, Set - для уникальных значений, Map - для коллекций с ключами и значениями. Чем точнее структура подходит под задачу, тем проще читать и поддерживать код.