Массивы в JavaScript: основы, методы и примеры кода
2026-02-21 23:31 Diff

#статьи

  • 3 фев 2026
  • 0

Массивный гайд для быстрого погружения.

Иллюстрация: Polina Vari для Skillbox Media

Онлайн-журнал для тех, кто влюблён в код и информационные технологии. Пишем для айтишников и об айтишниках.

В программировании часто нужно хранить набор значений в одном месте и обращаться к ним по порядку. Для этого в JavaScript используют массивы (Array) — специальный тип объекта для работы с упорядоченными коллекциями данных. В этой статье мы подробно поговорим про массивы, и вы узнаете, как их создавать и использовать. Кроме того, в конце вас ждут несколько несложных задач, с помощью которых вы сможете закрепить изученный материал.

Содержание

Массив (Array) в JavaScript — это упорядоченная коллекция элементов, где каждый элемент имеет свой числовой индекс (позицию). Индексация начинается с 0: первый элемент находится по индексу arr[0], второй — arr[1] и так далее. В отличие от многих других языков программирования, массивы в JS могут содержать элементы разных типов: числа, строки, логические значения true или false, объекты, функции и даже другие массивы.

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

// Без массива неудобно const item1 = 'молоко'; const item2 = 'хлеб'; const item3 = 'яйца'; // С массивом удобно и компактно const shoppingList = ['молоко', 'хлеб', 'яйца']; console.log(shoppingList); // ['молоко', 'хлеб', 'яйца'] // Можно легко добавить новый товар shoppingList.push('масло'); console.log(shoppingList); // ['молоко', 'хлеб', 'яйца', 'масло']

В JavaScript есть несколько способов создать массив. Самый простой — через квадратные скобки []. Это называется литералом массива. Пустые скобки создают пустой массив, а если добавить внутрь какие-то данные — получится массив с элементами.

// Пустой массив const arr = []; console.log(arr); // [] // Массив из трёх строк const animals = ['cat', 'dog', 'mouse']; console.log(animals); // ['cat', 'dog', 'mouse']

Есть и другой способ создать массив — вызвать конструктор Array (обычно через new Array(…)). Здесь важно помнить, что у него два режима работы: если передать одно число, оно будет воспринято как длина массива, и элементы при этом не заполняются значением undefined — создаются пустые слоты; а если передать несколько значений, они станут элементами массива — например, new Array(1, 2, 3) создаст массив из трёх чисел.

// Массив из трёх пустых элементов const emptyArray = new Array(3); console.log(emptyArray); // [empty × 3] // Массив из перечисленных элементов const numsArray = new Array(1, 2, 3); console.log(numsArray); // [1, 2, 3]

Кроме литерала [] и конструктора Array() есть методы Array.of() и Array.from(). Они помогают создавать массивы и преобразовывать другие значения в массивы.

Метод Array.of() создаёт массив из всех переданных значений. Он работает предсказуемее, чем Array():

const objs = Array.of(3, 'c', 'dfds'); console.log(objs); // [3, 'c', 'dfds']

Метод Array.from() преобразует строку и другие итерируемые значения в массив. Если вторым аргументом передать функцию, она сразу обработает каждый элемент.

// Превращаем строку в массив символов const charArr = Array.from('hello'); console.log(charArr); // ['h', 'e', 'l', 'l', 'o'] // Превращаем каждый символ строки в массив чисел const numArr = Array.from('12345', Number); console.log(numArr); // [1, 2, 3, 4, 5]

Массив хранит элементы по порядку, и у каждого свой номер — индекс. Нумерация начинается с нуля: первый элемент находится под индексом 0, второй — под индексом 1 и так далее.

const items = ['item01', 'item02', 'item03']; console.log(items[0]); // item01

Если вы попытаетесь обратиться к несуществующему индексу, JavaScript вернёт undefined. Это означает, что элемента с таким индексом в массиве нет. Важно понимать, что отрицательных индексов у массивов в JavaScript не существует в том смысле, в котором они есть, например, в Python. Поэтому запись items[-1] не вернёт последний элемент, а будет воспринята как обращение к свойству объекта с ключом -1. Соответственно, если такого свойства у массива нет (а по умолчанию его нет), результат всегда будет undefined.

// Отрицательный индекс console.log(items[-1]); // undefined // Несуществующий индекс console.log(items[999]); // undefined

Свойство length возвращает количество элементов в массиве.

const array = ['objFirst', 'obj2', 'obj3', 'objLast']; console.log(array.length); // 4

Это свойство удобно использовать для получения последнего элемента. Индексация начинается с 0, поэтому последний элемент всегда будет иметь индекс на единицу меньше длины массива.

console.log(array[array.length - 1]); // objLast

Массивы в JavaScript можно расширять или уменьшать — их размер не фиксирован. Если вы вручную измените length, то массив подстроится под новое значение.

При увеличении длины в массиве появятся пустые слоты (empty slots) — они существуют формально, но не содержат значений. При обращении к ним вы получите undefined.

const arrayLength = [1, 2, 3]; arrayLength.length = 5; console.log(arrayLength); // [1, 2, 3, empty × 2] console.log(arrayLength[4]); // undefined

При уменьшении длины массив обрезается, и все элементы с индексами больше или равными новому значению length будут безвозвратно удалены:

const truncatedArray = [1, 2, 3, 4, 5]; truncatedArray.length = 3; console.log(truncatedArray); // [1, 2, 3]

Чтобы выполнить действие для каждого элемента массива — например, вывести значения в консоль, обработать данные или изменить элементы, — используют перебор (итерацию). В JavaScript для этого есть несколько способов: классический цикл for, современный for…of и метод forEach(). Рассмотрим каждый на примере следующего массива:

const numbers = ['Один', 'Два', 'Три', 'Четыре', 'Пять'];

Цикл for начинается с индекса первого элемента и далее на каждой итерации увеличивает счётчик i на единицу, пока не достигнет значения length массива. Условие i < numbers.length определяет момент остановки. Этот способ даёт полный контроль: вы можете начать с любого индекса, изменить шаг итерации и даже перебирать массив в обратном порядке.

for (let i = 0; i < numbers.length; i++) { console.log(numbers[i]); } /* Один Два Три Четыре Пять */

Этот цикл перебирает значения массива напрямую — без счётчика и без необходимости обращаться к элементам по индексу. Для его использования достаточно указать массив, объявить переменную для хранения текущего элемента и использовать ключевое слово of:

for (const item of numbers) { console.log(item); } /* Один Два Три Четыре Пять */

forEach() — встроенный метод массива, который перебирает элементы по порядку и для каждого вызывает переданную функцию обратного вызова (callback). JavaScript автоматически передаёт в эту функцию три аргумента: текущий элемент, его индекс и ссылку на весь массив.

Сам по себе метод forEach() не изменяет исходный массив, однако внутри callback-функции вы можете явно модифицировать элементы через индекс или другие методы, если это требуется.

numbers.forEach((item, index) => { console.log(`${index}: ${item}`); }); /* 0: Один 1: Два 2: Три 3: Четыре 4: Пять */

В JavaScript есть четыре основных метода для добавления и удаления элементов массива: unshift() добавляет элемент в начало, push() — в конец, shift() удаляет первый элемент, а pop() — последний. Эти методы изменяют исходный массив и не создают новый.

const elements = ['element01', 'element02']; console.log(elements); // ['element01', 'element02'] // Добавляем элемент в начало массива elements.unshift('newElementAtStart'); console.log(elements); // ['newElementAtStart', 'element01', 'element02'] // Добавляем элемент в конец массива elements.push('newElementAtEnd'); console.log(elements); // ['newElementAtStart', 'element01', 'element02', 'newElementAtEnd'] // Удаляем первый элемент массива elements.shift(); console.log(elements); // ['element01', 'element02', 'newElementAtEnd'] // Удаляем последний элемент массива elements.pop(); console.log(elements); // ['element01', 'element02']

Методы shift() и pop() не только удаляют элементы из массива, но и возвращают удалённое значение. Это позволяет сохранить его в переменную и использовать дальше.

const elements2 = ['element01', 'element02', 'element03']; const first = elements2.shift(); console.log(first); // element01 console.log(elements2); // ['element02', 'element03'] const last = elements2.pop(); console.log(last); // element03 console.log(elements2); // ['element02']

Помимо методов добавления и удаления элементов, в JavaScript есть и другие инструменты для работы с массивами. Для удобства разделим их на две группы: методы, которые изменяют исходный массив (мутирующие), и методы, которые возвращают новый массив или значение.

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

splice(start, deleteCount, …items) — удаляет указанное количество элементов, начиная с позиции start, и при необходимости вставляет новые элементы на их место. Если вы не укажете deleteCount, то будут удалены все элементы от start и до конца массива.

const modifyArr = [1, 2, 3, 4]; modifyArr.splice(1, 2, 99); // Удаляем два элемента, начиная с индекса 1, и вставляем число 99 console.log(modifyArr); // [1, 99, 4]

sort() — меняет порядок элементов массива. По умолчанию этот метод преобразует элементы в строки и сравнивает их посимвольно. Из-за этого числа могут отсортироваться неправильно. Чтобы этого избежать, нужно передать функцию сравнения: (a, b) => a — b для сортировки по возрастанию или (a, b) => b — a — по убыванию.

const sortNums = [10, 2, 1]; sortNums.sort((a, b) => a - b); // Сортируем элементы по возрастанию console.log(sortNums); // [1, 2, 10]

reverse() — переворачивает массив, меняя порядок элементов на обратный.

const reverseArr = [1, 2, 3]; reverseArr.reverse(); console.log(reverseArr); // [3, 2, 1]

slice(start, end) — возвращает новый массив, который содержит копию элементов исходного массива от индекса start (включительно) до индекса end (не включая его).

const originalArray = [1, 2, 3, 4]; const part = originalArray.slice(1, 3); console.log(part); // [2, 3]

concat() — объединяет два или более массива и возвращает новый общий массив.

const firstPart = [1, 2]; const secondPart = [3, 4]; const merged = firstPart.concat(secondPart); console.log(merged); // [1, 2, 3, 4]

join(separator) — объединяет все элементы массива в одну строку, вставляя между ними указанный разделитель. Если разделитель не указан, по умолчанию метод использует запятую.

const letters = ['a', 'b', 'c']; const joined = letters.join('-'); console.log(joined); // "a-b-c"

map() — применяет переданную функцию к каждому элементу исходного массива и создаёт новый массив с результатами полученных преобразований.

const baseNumbers = [1, 2, 3]; const doubled = baseNumbers.map((n) => n * 2); console.log(doubled); // [2, 4, 6]

filter() — возвращает новый массив с элементами исходного массива, для которых переданная функция вернула true. Например, можно выбрать только чётные числа.

const filterSource = [1, 2, 3, 4]; const even = filterSource.filter((n) => n % 2 === 0); console.log(even); // [2, 4]

find() — возвращает первый элемент, который соответствует заданному условию, или undefined, если ничего не найдено. Для примера мы можем найти число больше единицы.

const searchSource = [1, 2, 3, 4, 5]; const found = searchSource.find((n) => n > 1); console.log(found); // 2

includes() — проверяет, содержится ли определённый элемент в выбранном массиве.

const checkSource = [1, 2, 3]; const hasTwo = checkSource.includes(2); console.log(hasTwo); // true

Иногда одного массива недостаточно, и вам нужно представить данные в виде таблицы, описать координаты на плоскости или сохранить несколько списков в одной структуре. В таких случаях используют вложенные массивы — массивы, элементы которых сами являются массивами.

Начнём с двумерного массива. Его удобно представлять как таблицу из строк и столбцов.

const matrix = [ [1, 2, 3], [4, 5, 6] ]; // Выводим массив табличным видом в консоль console.table(matrix); /* ┌─────────┬───┬───┬───┐ │ (index) │ 0 │ 1 │ 2 │ ├─────────┼───┼───┼───┤ │ 0 │ 1 │ 2 │ 3 │ │ 1 │ 4 │ 5 │ 6 │ └─────────┴───┴───┴───┘ */

Чтобы получить элемент из вложенного массива, необходимо указать два индекса: сначала номер строки (вложенного массива), затем номер столбца (элемента внутри него).

// Обращаемся к элементам двумерного массива console.log(matrix[0][2]); // 3 (первая строка, третий элемент) console.log(matrix[1][0]); // 4 (вторая строка, первый элемент)

Массивы в JavaScript могут быть вложены друг в друга на любое количество уровней. Степень вложенности называется глубиной массива. Одномерный массив (например, [1, 2, 3]) имеет глубину «один». Двумерный массив — тот, что мы создали выше, — имеет глубину «два». Трёхмерный массив, соответственно, — глубину «три», и так далее. Однако вы должны помнить: чем больше вложенность, тем сложнее работать с такими структурами. Код становится менее читаемым, а обращение к элементам требует больше индексов и увеличивает риск ошибок.

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

const cube = [ [[1, 2], [3, 4]], [[5, 6], [7, 8]] ]; // Выводим трёхмерный массив в консоль console.table(cube); /* ┌─────────┬──────────┬──────────┐ │ (index) │ 0 │ 1 │ ├─────────┼──────────┼──────────┤ │ 0 │ [ 1, 2 ] │ [ 3, 4 ] │ │ 1 │ [ 5, 6 ] │ [ 7, 8 ] │ └─────────┴──────────┴──────────┘ */ // Получаем доступ к элементу в трёхмерном массиве console.log(cube[1][1][1]); // 8 /* cube[1] — второй блок [[5, 6], [7, 8]] cube[1][1] — вторая строка [7, 8] cube[1][1][1] — второй элемент «8» */

Массив в JavaScript — это объект, а объекты в JavaScript сравниваются по ссылке, а не по содержимому. Операторы == и === проверяют не данные внутри массива, а то, ссылаются ли обе переменные на один и тот же объект в памяти. Поэтому, даже если два массива содержат одинаковые элементы в том же порядке, сравнение вернёт false, если это разные объекты.

const arrayOne = [1, 2]; const arrayTwo = [1, 2]; // Хотя содержимое одинаковое, это разные объекты в памяти console.log(arrayOne === arrayTwo); // false

Равенство становится возможным только тогда, когда обе переменные указывают на один и тот же массив в памяти. В этом случае нет двух отдельных массивов — есть один объект-массив и две ссылки (переменные), которые указывают на него. Именно поэтому оператор === возвращает true: сравниваются не значения, а адреса в памяти, и они совпадают.

const listA = [1, 2, 3]; const listB = listA; // Две переменные указывают на один и тот же массив в памяти console.log(listA === listB); // true

Если нужно сравнить содержимое массивов (а не ссылки), в JavaScript для этого нет готового оператора или метода. Поэтому сравнение обычно делают вручную: сначала проверяют длину, затем сравнивают элементы по индексам. Если хотя бы один элемент отличается, массивы считаются разными. Один из простых и читабельных вариантов — через метод every():

const arraysEqual = (a, b) => a.length === b.length && a.every((value, i) => value === b[i]); const firstList = [1, 2, 3]; const secondList = [1, 2, 3]; const thirdList = [1, 2, 4]; console.log(arraysEqual(firstList, secondList)); // true console.log(arraysEqual(firstList, thirdList)); // false

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

В JavaScript существует множество методов для работы с массивами, и при их использовании неизбежно возникают нюансы. Однако мы заметили, что ошибки часто появляются не из-за «сложных» методов, а из-за мелочей: неверной проверки типа, попыток обратиться к несуществующим элементам, ошибок в переборе и прочего. В этом разделе мы собрали самые частые промахи, которые встречаются у новичков, и показываем, как их избежать.

При работе с массивами вы можете случайно попытаться определить их тип с помощью оператора typeof. Однако в JS массивы реализованы как особый вид объектов, поэтому typeof возвращает object. Этот оператор не различает обычные объекты и массивы.

const checkTypeArray = []; console.log(typeof checkTypeArray); // "object"

Для проверки используйте метод Array.isArray(), который принимает значение и возвращает true, если это массив, и false — если нет.

console.log(Array.isArray(checkTypeArray)); // true

Некоторые разработчики, знакомые с другими языками вроде Python, предполагают, что отрицательный индекс обращается к элементам с конца массива. В JavaScript это не работает: отрицательное значение воспринимается не как индекс элемента, а как имя свойства объекта. А поскольку такого свойства у массива нет, результатом будет undefined.

const fruitList = ["яблоко", "груша"]; console.log(fruitList[-1]); // undefined

Чтобы получить элемент с конца массива, используйте метод at().

console.log(fruitList.at(-1)); // груша

Свойство length можно изменять напрямую, и иногда его используют для очистки массива, присваивая length = 0. С технической точки зрения это допустимо, но важно понимать: изменение length модифицирует сам массив, а не создаёт новый. Поэтому если этот массив используется в других частях программы, изменение length затронет все эти места.

Чтобы избежать неожиданных побочных эффектов и сохранить исходные данные в безопасности, мы рекомендуем перед изменением массива создать его копию. Например, используйте spread-оператор (…), который создаёт поверхностную копию массива:

const numericSeries = [1, 2, 3]; const backupSeries = [...numericSeries]; // Создаём копию перед очисткой numericSeries.length = 0; // Очищаем массив console.log(numericSeries); // [] console.log(backupSeries); // [1, 2, 3] (копия осталась)

Эта ошибка возникает при переборе массива циклом for, когда в условии используется <= вместо <. В результате цикл выполняет на шаг больше положенного и обращается к элементу с индексом, равным length. А поскольку такого индекса нет, в конце выводится undefined.

const iterationItems = [1, 2, 3]; console.log("Цикл с ошибкой (<=):"); for (let i = 0; i <= iterationItems.length; i++) { console.log(iterationItems[i]); // undefined }

Добавляем строгое сравнение в условии — и всё в порядке.

console.log("Верный цикл (<):"); for (let i = 0; i < iterationItems.length; i++) { console.log(iterationItems[i]); } /* 1 2 3 */

Когда вы передаёте массив в функцию, туда попадает не копия, а ссылка на тот же самый объект в памяти. Это значит, что любые изменения массива внутри функции напрямую затрагивают исходный массив. Например, если функция добавляет новый элемент через метод push(), этот элемент появится и в исходном массиве за пределами функции.

const modifyInPlace = (arr) => { arr.push("новый элемент"); }; const sourceList = [1, 2, 3]; modifyInPlace(sourceList); console.log(sourceList); // [1, 2, 3, "новый элемент"]

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

const modifyWithCopy = (arr) => { const copy = [...arr]; copy.push("ещё один элемент"); return copy; }; const originalList = [1, 2, 3]; const updatedList = modifyWithCopy(originalList); console.log(originalList); // [1, 2, 3] (оригинал не изменился) console.log(updatedList); // [1, 2, 3, "ещё один элемент"]

Закрепим знания и разберём несколько простых задач на работу с массивами. Если вам нужно больше практики, рекомендуем зарегистрироваться на платформе Codewars и решать по одной задаче в день. Регулярная практика поможет вам быстрее освоить синтаксис, научиться применять методы массивов в реальных ситуациях и развить алгоритмическое мышление.

Предположим, у нас есть массив чисел, и нам нужно посчитать количество положительных, отрицательных и нулевых элементов.

const taskNumbers = [-5, 0, 3, -8, 12, 0, -2];

Решение

Создадим переменные-счётчики для каждого типа значений и пройдём по массиву циклом for of.

let positiveCount = 0; let negativeCount = 0; let zeroCount = 0; for (const num of taskNumbers) { if (num > 0) { positiveCount++; } else if (num < 0) { negativeCount++; } else { zeroCount++; } } console.log({ positiveCount, negativeCount, zeroCount }); // { positiveCount: 2, negativeCount: 3, zeroCount: 2 }

У вас есть массив с ценами, которые нельзя менять. Вам нужно получить новый массив со скидкой 15%, но убрать из результата товары, которые после скидки стоят меньше 100.

const productPrices = [ 100, 150, 80, 200, 50, 300, 120, 90, 450, 60, 1000, 15, 250, 500, 75, 130, 800, 40, 110, 600 ];

Решение

Сначала с помощью метода map() мы проходим по исходному массиву и для каждой цены вычисляем новую — получается новый массив значений. Затем применяем filter() к этому массиву и оставляем только те цены, которые после скидки составляют не менее 100.

const discountedPrices = productPrices.map((price) => price * 0.85); const finalPrices = discountedPrices.filter((price) => price >= 100); console.log(finalPrices); // [ 127.5, 170, 255, 102, 382.5, 850, 212.5, 425, 110.5, 680, 510 ]

Предположим, у вас есть массив имён гостей из формы на сайте. В нём есть лишние пробелы и пустые строки. Вам нужно очистить данные, оставить только имена и собрать их в одну строку.

const rawNames = [ " Алексей ", " ", "мария ", " С ", " Игорь", "ольга", " Пётр ", "Елена ", " ", "александр", "Дмитрий", "светлана", " И ", "нИкИтА", " Анна ", " Борис", " катЯ ", " ", "владимир", "артём" ];

Решение

Чтобы решить эту задачу, вам необходимо последовательно обработать массив с помощью изученных в этой статье методов, а также некоторых методов строк. Строковые методы в JS вы должны были изучить перед тем, как изучать массивы.

Вот порядок действий:

  • очистите строки от пробелов методом trim() через map();
  • удалите короткие значения через filter(), проверяя свойство length;
  • приведите имена к правильному регистру через map(), используя методы toUpperCase() и toLowerCase();
  • добавьте приставку «Гость» через map();

В завершение объедините всё в строку методом join() и выведите результат.

// Убираем лишние пробелы по краям каждого имени const trimmedNames = rawNames.map((name) => name.trim()); // Оставляем только те имена, где больше одного символа const validNames = trimmedNames.filter((name) => name.length > 1); // Исправляем регистр: первая буква заглавная, остальные строчные const capitalizedNames = validNames.map((name) => { return name[0].toUpperCase() + name.slice(1).toLowerCase(); }); // Добавляем к каждому имени приставку «Гость» const guestNames = capitalizedNames.map((name) => `Гость: ${name}`); // Собираем всё в одну строку с разделителем ", " const guestListString = guestNames.join(", "); console.log(guestListString); // Гость: Алексей, Гость: Мария, Гость: Игорь, Гость: Ольга, Гость: Пётр, Гость: Елена, Гость: Александр, Гость: Дмитрий, Гость: Светлана, Гость: Никита, Гость: Анна, Гость: Борис, Гость: Катя, Гость: Владимир, Гость: Артём
Курс с трудоустройством: «Профессия Фронтенд-разработчик + ИИ» Узнать о курсе