Массивы в JavaScript являются объектами, которые содержат, как правило, однотипные элементы, т.е. только числа, строки, булевы величины (true или false) или другие объекты, в том числе и другие массивы. Эти элементы расположены друг за другом, т.е. упорядоченно. Порядок расположения элементов определяется индексами, т.е. номерами, с помощью которых можно обращаться, получать и изменять элементы массива.

Особенности массива в JavaScript

  • Объявление массива выделяет последовательные блоки памяти.
  • Каждый блок памяти представляет элемент массива.
  • Элементы массива идентифицируются уникальным целым числом, называемым индексом / индексом элемента.
  • Массивы также, как и переменные, должны быть объявлены до их использования.
  • Инициализация массива заключается в заполнении массива элементами.

Объявление массива

Для того чтобы объявить массив, используются 2 способа:
1. С помощью литерала массива:

2. Используя встроенный объект Array:

Посмотрим, что будет выведено:

В консоли мы увидим такое отображение массивов:

Объявление массива

Пустой массив, объявленный любым способом, представлен в виде двух квадратных скобок. Массив из 5 элементов с неопределенными  значениями показан, как массив из 5 пустых (empty) ячеек. Массивы, заполненные элементами, выводятся с указанием их количества и значениями самих элементов.

Длина массива

Часто используемым свойством массива является его длина (length). Она показывает количество элементов:

В результате мы получим цифру. В нашем примере это 5.

Примечание: слово  length первоначально довольно сложно для написания. Очень легко написать его так: lenght или legnth, однако это будет неверно с точки зрения JavaScript. Поэтому имеет смысл использовать для написания кода текстовые редакторы, где заложены подсказки.

Обращение к элементам массива

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

Давайте посмотрим на результат:

Вы можете увидеть, что 2 первых элемента массива изменились, остальные 3 остались неизменными, далее появились 2 пустых (empty) элемента и последний элемент имеет значение 15. Т.е. наш массив не только изменился с точки зрения значений элементов, он еще и увеличился в размере.

Элементы массива

Использование цикла for для перебора массива

Чаще всего необходимо изменить не только один-два элемента массива, а их все. Для этого с очень давних времен используется цикл for. Например, нам необходимо добавить ко всем элементам числового массива число 5:

Вы можете сравнить значения элементов до и после использования цикла for. В результате использования цикла мы получили измененный массив.

Результат перебора массива циклом for

Мы можем также использовать метод forEach() для перебора и манипулирования элементами массива.

Перебираем элементы с методом forEach()

Метод arr.forEach() позволяет запускать функцию для каждого элемента массива, таким образом позволяя перебрать элементы массива аналогично тому, как это делает цикл for. Метод forEach() выполняет заданную функцию (ее еще называют callback) один раз для каждого элемента, находящегося в массиве в порядке возрастания, т.е. перебирает элементы от нулевого индекса до последнего. Функция callback не будет вызвана для удалённых или пропущенных элементов массива. Для тех элементов, которые  присутствуют в массиве и имеют значение undefined, она тоже сработает.

Синтаксис метода forEach() имеет 3 варианта в зависимости от количества нужных вам аргументов (от одного до трех).

Вариант 1: функция вызывается с одним обязательным аргументом, который позволяет манипулировать значением элемента. В примере мы используем значение каждого элемента массива, чтобы разделить его на 4 и вывести полученный результат.

Пример вживую (для наглядности заменен console.log() на document.write()):

Вариант 22 аргумента дают возможность использовать доступ не только к элементу, но и к его индексу:

Результат:

Метод forEach(function(item, i){ ... })

Вариант 3: последний вариант написания этого метода - с 3 аргументами: значением элемента, его индексом и всем массивом. В примере использован синтаксис стрелочной функции из стандарта ES6.

Смотрим примеры в действии:

Метод forEach() очень популярен для перебора ключей или значений свойств объектов, которые можно преобразовать в массив методами Object.keys() или Object.values().

Особенности метода array.forEach()

Поскольку метод array.forEach() - это аналог цикла for(), то можно предположить, что его можно прервать такими операторами, как break и continue, а поскольку внутри него работает функция-callback, то завершить выполнение этой функции можно с помощью оператора return. Однако не тут-то было.

При использовании операторов break и continue в консоли вы увидите синтаксическую ошибку, которая сообщает, что эти операторы можно использовать только в циклах.

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

В официальной документации на MDN есть примечание по этому поводу:

Не существует способа остановить или прервать цикл forEach() кроме как выбрасыванием исключения. Если это требуется, метод forEach() неправильный выбор. Используйте обычные циклы. Если нужно протестировать элементы массива на условие и нужно вернуть булево значение, вы должны воспользоваться методами Array.prototype.every() или Array.prototype.some().

Обратите внимание, что метод forEach() не изменяет исходный массив, он только проводит какие-либо операции с его элементами и позволяет их вывести на экран. Если необходимо перезаписать значения и сохранить их в новый массив, необходимо array.map().

Создаем новый массив на основе старого с помощью array.map()

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

Рассмотрим простой пример, в котором нам необходимо записать корень квадратный из значений элементов одного массива в другой:

Результат:

Метод array.map(function(item){ ... })

Давайте посмотрим, как мы можем использовать метод map() в стрелочной функции с 2-мя аргументами:

Результат применения метода:

Давайте еще рассмотрим метод map() в применении к объектам и в том, что функция callback, которая вызывается в методе map(), будет записана отдельно. Пример имеет такой код:

Результат в виде нового массива:

Метод array.map(function(item, i){ ... }) для объектов

Замечание: метод map() не выполняется для элементов, не имеющих значений.

Благодаря статье .map(), filter() & .reduce() — animated вы можете посмотреть на работу 3-х методов массивов в виде анимации.  И первый из них - это map().

Метод map() для массивов

Подробнее о работе методов forEach(), map()  и reduce() и их замене циклом for() вы можете прочитать в статье "Замена методов массива forEach(), map(), filter(), reduce() с помощью цикла for".

Метод array.join() для вывода массива в виде строки

Метод array.join('разделитель') преобразует массив в строку, склеивая элементы с помощью разделителя. Например:

Смотрим, что получилось:

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

Добавление и удаление элементов массива

Массивы можно дополнять и уменьшать с помощью следующих методов:

Все эти методы изменяют исходный массив, увеличивая или уменьшая количество его элементов.

Добавляем элементы в конец массива методом push()

Этот метод подразумевает, что вы добавляете в конец массива хотя бы один элемент, значение которого указываете в скобках в качестве аргумента. Однако с помощью array.push() можно добавить любое количество элементов, перечислив в скобках их значения через запятую:

На скриншоте можно посмотреть изменения в массиве.

Добавляем элементы в конец массива методом push()

Удаляем последний элемент массива методом pop()

Метод array.pop() удаляет самый последний элемент массива и возвращает его в качестве значения. То есть вы можете это элемент записать в переменную и потом использовать, а можете никуда не записывать, и этот элемент просто исчезнет из массива. Используем последний вариант массива с месяцами из предыдущего примера:

Получим такой результат в консоли:

Метод массива pop()

Удаляем первый элемент массива методом shift()

Метод array.shift()  подобен по действию array.pop() - он удаляет первый элемент массива (элемент с нулевым индексом) и возвращает его в качестве значения, например:

Посмотрим результат на скриншоте:
Метод shift()

Добавляем элементы в начало массива методом unshift()

Для того чтобы добавить один или несколько элементов в начало массива, необходимо вызвать метод array.unshift(elem1[, elem2, elem3]). Как и в случае с методом array.push() вы можете добавить один или больше элементов. Давайте добавим зимние месяцы в начало массива monthes:

Результат на скриншоте:

Метод unshift()

Вырезаем элементы с помощью array.splice(start[, number, item1, ....., itemX]) и добавляем новые

Метод splice() позволяет вырезать (другими словами - удалить) часть массива и вставить на место вырезанных элементов новые, если есть такая необходимость. В скобках метода splice() нужно указать хотя бы один аргумент, который показывает, с какого индекса начнется вырезание элементов. Второй аргумент показывает, сколько элементов нужно вырезать, а третий и последующие аргументы - какие элементы массива мы вставляем вместо удаляемых. Те элементы, которые вырезаются, могут быть сохранены в переменную в виде отдельного массива.

Рассмотрим пример с теми же месяцами:

Вот, что показывает консоль:

Метод splice()

В первой строке мы видим, что в переменную с именем spliceMonthes переместились все элементы, начиная с 3-го индекса. Во второй строке мы удалили последний элемент массива (индекс -1) и вместо него добавили 3 новых месяца.

Метод splice() можно использовать совсем без аргументов, но в этом случае мы получим пустой массив, если захотим записать его в переменную:

splice()

Вопрос заключается в том, зачем вам это нужно, если можно просто создать пустой массив?

Очистка массива

Предположим, в какой-то момент времени нам необходимо удалить все элементы массива, оставив массив пустым. Для этого достаточно назначить в качестве значения массиву пустые квадратные скобки или обнулить длину массива (array.length = 0):

После очистки массива любым способом мы получаем пустой массив.

Очистка массива

Удаление элементов массива:

В этом случае длина массива не изменяется, но он заполняется пустыми значениями. удаление элементов массива

Используем метод array.slice() для копирования части массива

Метод array.slice([start[, end]]) позволяет скопировать часть одного массива в другой. Для этого нужно указать с какого индекса (номера элемента) мы начинаем копирование (аргумент start) и до какого индекса продолжаем копирование (аргумент end) . Т.е. элемент с индексом end не включается в копирование.

Смотрим, какие элементы мы скопировали:

Метод array.slice()

Метод slice() не изменяет исходный массив, что видно из скриншота.

Если в методе array.slice() не указывать ни одного параметра в скобках, будет скопирован весь массив от начала до конца.

Копирование массивов

Иногда необходимо сохранить данные одного массива в другой, чтобы оставить их, например, для последующего сравнения. Первым делом в голову приходит мысль о присвоении массива из одной переменной в другую. Например,

В консоли вы увидите такой результат:

Копирование массивов в виде ссылки

Получается, что мы не скопировали массив, а сделали в переменной arr2 сcылку на массив arr1. Именно поэтому массивы изменились одинаково после добавления элементов строкой arr1.push().

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

Результат в консоли:

Копирование массива с помощью метода slice

Метод slice() раньше часто использовался для преобразования псевдомассивов, к которым относятся различные коллекции элементов, в обычные массивы с помощью метода call() для того, чтобы в них можно было использовать методы массивов.

Если вас интересует процессы копирования объектов, то стоит прочитать статью "Способы копирования объектов в JavaScript".

Объединяем массивы методом array.concat()

Если стоит задача добавить значения одного массива в конец другого, можно использовать метод array.concat(). Например, нужно объединить студентов разных групп в одну:

Результат объединения массивов нужно записать в новый массив, присвоив его переменной. В итоге в консоли увидим такие элементы массивов:

Метод array.concat()

При этом исходные массивы не изменяются и могут быть использованы в коде еще раз.

Объединять методом array.concat() можно не только 2 разных массива, но и массив с другими значениями. Например, так:

Мы перезаписываем данные уже существующей переменной newGroup из предыдущего кода, добавив данные.

Метод array.concat() позволяет копировать числовые, строковые и булевы значения в новый массив непосредственно по значению, а вот объекты будут переданы как ссылка.

В консоли мы получим такой массив:

Объединение объектов в масссив методом concat

Теперь продолжим код:

Изменение объектов в массиве

И в первом, и во втором вызове console.log(cats) видим изменение свойства age.

Стоит отметить, что копирование значений массивов после появления стандарта ES6 стало доступно и с помощью оператора spread, который записывается в виде 3-х точек (...).

Метод reduce() и reduceRight() для выполнения операций с элементами массива

Метод reduce() можно использовать, когда необходимо произвести некоторые арифметические операции со всеми элементами массива, например, посчитать их сумму. Ранее эти действия  проделывали с помощью цикла for. Поэтому проверим, как выполняются действия в функции и в цикле.

Проверим, что нам покажет console браузера. На скриншоте видно, что происходят идентичные операции.

reduce-for

То есть при каждом вызове функции происходит следующее: к значению 0-го элемента прибавляется значение 1-го элемента, затем к полученному результату, который записывается в переменную total, прибавляется значение 2-го, 3-го, n-го элемента и на выходе из функции мы получили результат, который содержит сумму всех значений элементов массива.

Синтаксис этого метода подразумевает, что параметров при вызове callback-функции можно использовать больше аргументов:

Параметр index и array используются редко, а вот необходимость в startValue может возникнуть, т.к.  бывает необходимо посчитать, например, сумму или разность, начиная не с 0-го индекса, а с какого-то значения, полученного ранее. Например,

Метод reduce
Третья строка этого примера нужна для того, чтобы понять, как выполняются действия. Давайте посмотрим на скриншоте, с какого  числа начинается подсчет разницы и что выводится при каждой итерации.

Кроме метода reduce() существует метод reduceRight(), который выполняет те же действия, но перебирает массив не от начала к концу, а наоборот - с конца, т.е. с последнего элемента, в начало.

Анимированное представление работы метода reduce():

Метод reduce() для массивов

Еще несколько примеров работы с методом reduce() вы найдете в статье Замена методов массивов forEach(), map(), filter(), reduce() циклом for.

Сортировка массива

Метод array.sort() предназначен для сортировки элементов массива. При этом он возвращает отсортированный массив. Порядок сортировки по умолчанию соответствует порядку кодовых точек Unicode. Вы можете задать свой вариант сортировки массива в функции.

Рассмотрим пример сортировки числового массива и массива имен (ников).

Результат работы метода array.sort() представлен на скриншоте:

array.sort()

Обратите внимание, что метод array.sort() изменяет исходный массив.

Если мы присмотримся к сортировке числового массива, то можно увидеть, что не все числа идут в привычном нам порядке от меньшего к большему. Это происходит потому, что в таблице символов Unicode цифра 7, как и 70, и 700 идут после 5, 54, 6, 60 и т.п. Для того чтобы сортировка шла в нужном порядке, используем такую функцию:

Результат теперь выглядит правильно с точки зрения числового ряда:

Функция для сортировки

Пример использования методов sort() и map() вы найдете в статье "Обработка событий Drag & Drop в JavaScript" для формирования случайного порядка элементов в массиве-списке из перетаскиваемых элементов.

Фильтрация массива

Фильтрация массива подразумевает, что мы выбираем часть элементов одного массива и переносим их в другой по определенному признаку. Для этого в JavaScript есть метод array.filter(), синтаксис которого подразумевает вызов callback-функции, аналогичной той, которая работает в методах forEach(), map(), reduce().

Синтаксис метода filter() подобен другим аналогичным методам.

Действие же callback-функции строится по механизму проверки некоторого условия. Если элемент удовлетворяет этому условию, то он помещается в новый массив, например:

На скриншоте можно посмотреть результат работы метода array.filter():

Метод array.filter()

Как можно видеть из данных console.log() изменения не коснутся исходного массива.

Анимированное представление работы метода filter():

Метод filter() для массивов

Методы array.every() и array.some() для получения данных об элементах массива

Методы every() и some() используются для проверки массива на наличие элемента(-ов), соответствующих определенному условию. Разница между ними состоит в том, что метод array.every(callback{}) возвращает true, если вызов функции  callback вернёт true для каждого элемента массива, а метод array.some(callback{}) возвращает true, если вызов функции  callback вернёт true для какого-нибудь элемента arr. Функция callback вызывается с тремя аргументами: значением элемента, индексом элемента и массивом, по которому осуществляется проход.

Синтаксис методов

Рассмотрим пример с использованием метода array.every()

Массивы различаются 1 цифрой, но в первом все числа четные, а во втором - не все, поэтому и результат работы метода отличается.

Рассмотрим пример с использованием метода array.some()

В первом массиве есть имя "John", поэтому метод array.some() вернул true, а во втором есть подобное имя, но тем не менее не совпадающее с "John", поэтому метод вернул false.

Сравнение массивов с помощью методов array.every() и array.sort()

Сравнение массивов не всегда является простой операцией. Например, у нас есть 3 массива, из которых 2 имеют одинаковые значения, а третий - те же значения, но в другом порядке. Сравним эти массивы с помощью оператора строго равенства '===':

В консоли вы увидите, что первый массив не равен второму (странно, учитывая, что у них одинаковые значения), не равен третьему (понятно, т.к. значения, хоть и совпадают, но идут в другой последовательности) и равен массиву clonArr1 , т.к. на самом деле это ссылка на массив  numArr1, но с другим именем, т.е. как бы numArr1 проверяется на равенство самому себе.

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

Используем для этой цели проверку массивов с помошью метода array.every(), т.к. он возвращает true или false в зависимости от того, выполняется ли некое условие. В данном примере будет учитываться точное совпадение элементов каждого массива.

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

При использовании этой функции мы столкнемся с одним интересным моментом: метод array.sort() меняет порядок следования элементов, что видно из скриншота консоли:
Сравнение массивов с помощью методов sort() и every()

Если для вас важно сохранить порядок элементов в массиве, код функции сравнения стоит изменить, скопировав оба массива во временные переменные, например, с помощью оператора spread:

Тогда в консоли мы увидим другой результат:

Сравнение массивов без учета порядка следования элементов

Пример использования методов массивов

В примере ниже от Envato Tuts+ вы найдете многие из перечисленных методов массивов. Это пример их использования на странице с реальным контентом для сортировки записей.

See the Pen Search with Vanilla JavaScript by Envato Tuts+ (@tutsplus) on CodePen.

Обращаем порядок элементов массива методом array.reverse()

Реверс подразумевает обратный ход, поэтому метод array.reverse() преобразует порядок следования элементов в массиве на обратный начальному, т.е. первый элемент становится последним, второй - предпоследним и т.д. Пример кода:

После использования метода массив изменяется и выглядит так:

array.reverse()

В примере ниже на основе массива объектов созданы 3 статьи. С помощью метода array.reverse() мы изменяем порядок их вывода при клике на кнопку "Обратный порядок" в самом верху примера.

See the Pen Operator && and Array.reverse() by Elen (@ambassador) on CodePen.

Ассоциативные массивы

Ассоциативные массивы в большей степени используются в PHP, чем в JS, но и в последнем они применяются время от времени. Отличие ассоциативных массивов от обычных заключается в том, что вместо нумерованных индексов в них используются именованные индексы. Например, у нас есть массив с некоторыми данными по сайту, которые удобней определять не цифрами (нумерованными индексы), а словами (т.е. строками):

Для того чтобы вывести этот массив, не получится использовать цикл for или метод forEach(). Зато можно вывести все данные с помощью цикла for...in.

Посмотрим, что получилось (в примере была замена console.log() на document.write()):

Создаем массив методом Array.from() из коллекций элементов

В JavaScript ранее было проблемой использование методов массивов для массивоподобных коллекций html-элементов страницы или аргументов функции. Однако метод Array.from() отлично решает эту проблему.

Рассмотрим 2 варианта обращения к элементам <p class="p-example">, которые находятся внутри <div id="example-from">: с помощью современного метода document.querySelectorAll() и значительно более старого getElementsByTagName('p').

С закомментированной строкой //pCollection = Array.from(pCollection) вы получите ошибку в консоли при попытке вызвать метод forEach() для коллекции html-элементов, а не для коллекции NodeList.

Коллекция html-элементов

В примере ниже вы можете попробовать, нажимая на разные кнопки, как работает коллекции элементов, выбранные 3-мя методами. Для последних 2-х обязательно использовать метод Array.from() для преобразования HTMLCollection в обычный массив.

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sit dignissimos voluptatum, nostrum atque quibusdam illo voluptatibus cumque.

Commodi totam, odio pariatur labore, sequi suscipit asperiores, blanditiis repellendus eos eius, et nesciunt culpa iusto reiciendis.

Dolor nostrum quam eaque, numquam nesciunt illo totam obcaecati voluptate laborum, repellat fugiat blanditiis dicta quaerat delectus?

Adipisci nemo recusandae cupiditate doloribus repudiandae ipsam nobis dolore? Alias provident beatae, vel eius sapiente non itaque.

Voluptatibus ad voluptates, placeat illum excepturi velit, asperiores labore, accusamus iste error iure aliquam recusandae molestiae nostrum!

Посмотреть о способах обращения к элементам на html-странице вы можете в статье Выбор элементов html-страницы с помощью JavaScript.

Автор: Админ

2 комментария

  1. Жаль, что метод array.splice() нельзя использовать для строк...

    • Зато можно использовать string.slice() и конкатенировать строку, как нужно.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *