Массивы в JavaScript

Массивы в JavaScript #

Массив — упорядоченная коллекция значений с числовыми индексами от нуля. В JavaScript массив — особый вид объекта: длина length, методы вроде push и возможность хранить элементы любых типов в одном списке. Корзина, треклист и таблица очков естественно моделируются массивом.


Создание массива #

const cart = []
const playlist = ['Night Drive', 'Soft Code', 'Buffer']
const scores = new Array(3) // [empty × 3] — редко нужно на практике

const fromString = Array.from('abc') // ["a", "b", "c"]
const filled = Array.from({ length: 3 }, (_, i) => i + 1) // [1, 2, 3]

Литерал [] — самый читаемый способ.


Доступ и изменение по индексу #

const tracks = ['A', 'B', 'C']

tracks[0] // "A"
tracks[1] = 'Beta'
tracks[tracks.length] = 'D' // добавит в конец, но length станет 4 при индексе 3

tracks.length // 4

Индекс за пределами даёт undefined, не ошибку:

tracks[99] // undefined

length и «дырявые» массивы #

length — на один больше максимального индекса + 1, а не «количество реальных элементов»:

const sparse = []
sparse[5] = 'x'
sparse.length // 6
sparse[0] // undefined

Такие массивы редко нужны в прикладном коде; для списков заказов держите плотные массивы объектов.

Укоротить массив можно присвоением length:

const ids = [10, 20, 30, 40]
ids.length = 2
ids // [10, 20]

Добавление и удаление на концах #

const queue = ['order-1']

queue.push('order-2') // 2 — новая length
queue.pop() // "order-2"

queue.unshift('priority') // в начало
queue.shift() // с начала

push/pop — конец (стек), shift/unshift — начало (очередь, но дороже на больших массивах).


Мутабельность и const #

const запрещает переназначить переменную, но не запрещает менять содержимое:

const cart = [{ sku: 'kb-01', qty: 1 }]

cart.push({ sku: 'ms-02', qty: 2 }) // допустимо
cart[0].qty = 3 // допустимо
// cart = [] — TypeError

Для иммутабельных обновлений создавайте новый массив (подробнее в Методы массивов).


Перебор #

const deliverySteps = ['собран', 'в пути', 'у подъезда']

for (let i = 0; i < deliverySteps.length; i++) {
  console.log(i, deliverySteps[i])
}

for (const step of deliverySteps) {
  console.log(step)
}

deliverySteps.forEach((step, index) => {
  console.log(index, step)
})

for...of — по значениям; for...in по массиву лучше не использовать (перечисляет и индексы, и унаследованные ключи).


Проверка «это массив?» #

Array.isArray([1, 2]) // true
Array.isArray('text') // false
typeof [] // "object" — недостаточно

Копирование и объединение #

Поверхностная копия:

const original = [{ id: 1 }, { id: 2 }]
const shallow = [...original]
const also = original.slice()

shallow[0].id = 99
original[0].id // 99 — вложенные объекты общие

Объединение:

const wishlist = ['pad-01']
const cart = ['kb-01', 'ms-02']

const combined = [...wishlist, ...cart] // ["pad-01", "kb-01", "ms-02"]
const withExtra = cart.concat('cable-03')

Глубокое клонирование вложенных структур — отдельная тема (structuredClone в современных средах).


Поиск элемента (базовый уровень) #

const skus = ['kb-01', 'ms-02', 'hp-09']

skus.indexOf('ms-02') // 1
skus.indexOf('xx') // -1

skus.includes('hp-09') // true

Для объектов в корзине indexOf ищет по ссылке, не по полю sku — для этого есть find в следующей главе.


Преобразование в строку #

['a', 'b', 'c'].join('-') // "a-b-c"
[1, 2, 3].toString() // "1,2,3"

Не используйте неявное приведение массива к строке в логике — явный join понятнее.


Многомерные и вложенные списки #

const scoreboard = [
  ['Аня', 1200],
  ['Борис', 980],
  ['Вика', 1450],
]

scoreboard[2][1] // 1450

Таблица очков — массив пар или массив объектов { name, score }; второй вариант масштабируется лучше.


Практика: корзина как массив объектов #

const cart = [
  { sku: 'kb-01', title: 'Клавиатура', price: 4900, qty: 1 },
  { sku: 'ms-02', title: 'Мышь', price: 1290, qty: 2 },
]

function lineCount(cart) {
  return cart.reduce((sum, line) => sum + line.qty, 0)
}

function hasSku(cart, sku) {
  return cart.some((line) => line.sku === sku)
}

lineCount(cart) // 3
hasSku(cart, 'hp-09') // false
function removeSku(cart, sku) {
  return cart.filter((line) => line.sku !== sku)
}

removeSku(cart, 'ms-02')
// [{ sku: 'kb-01', ... }] — новый массив, cart не тронут

Практика: плейлист с порядком #

const playlist = [
  { id: 't1', title: 'Intro', durationSec: 45 },
  { id: 't2', title: 'Main', durationSec: 210 },
]

function moveTrack(list, fromIndex, toIndex) {
  const next = [...list]
  const [item] = next.splice(fromIndex, 1)
  next.splice(toIndex, 0, item)
  return next
}

moveTrack(playlist, 0, 1)
// [{ id: 't2', ... }, { id: 't1', ... }]

Итог #

  • Массив — упорядоченный список с индексами с нуля и свойством length.
  • const не делает массив неизменяемым; для новых версий списка используйте копию и методы без мутации.
  • push/pop/shift/unshift меняют исходный массив; spread и slice помогают копировать.
  • Array.isArray — надёжная проверка типа.
  • Корзины и плейлисты удобнее хранить как массивы объектов, а не параллельные массивы полей.

См. также #