Как обходить массивы правильно, профессионально и самое главное читабельно?
В JavaScript есть много способов обойти массив, и каждый из них служит для разных целей. Наверно самый популярный из них это обход при помощи цикла for.
Однако в арсенале JavaScript есть более удобные в использовании и более выразительные средства для обхода массива. Однако многие разработчики ограничиваются только for, forEach или map.
О методах forEach, map, filter, every, some, flatMap
Разберем доступные методы подробнее. Начнем с методов forEach, map, filter, every, some, flatMap. Все эти методы появились еще в версии ES5, кроме flatMap, который появился в ES2019.
Почему я решил объединить их в общую группу? У всех этих методов одинаковая сигнатура параметров callback и thisArg.
callback
Обязательный аргумент. Функция, которая вызывается по одному разу для каждого элемента массива. Она принимает несколько аргументов:
- currentValue (обязательный) — текущий обрабатываемый элемент в массиве;
- index (необязательный) — индекс текущего обрабатываемого элемента в массиве;
- array (необязательный) — массив, по которому осуществляется обход.
thisArg
Необязательный аргумент. Значение, используемое в качестве this при вызове callback функции.
О чем необходимо помнить?
- Сallback функция не вызывается для индексов, которые были удалены. Мутирование массива в callback функции не является хорошей практикой. Здесь такой подход использован лишь ради примера.
- Сallback функция не вызывается для индексов, значения которым никогда не присваивались, например, для пропущенных элементов.
- Однако, callback функция будет вызвана для элементов, которые присутствуют в массиве и имеют значение undefined.
- Если необходимо обойти пропущенные элементы, нужно воспользоваться циклом for / for-of.
- Callback функции можно передавать просто как имя функции, которая описана в другом месте, главное, чтобы аргументы совпадали. parseInt, который первым аргументом принимает значение, а вторым — основание системы счисления, является показательным примером.
- Диапазон элементов, устанавливается до первого вызова callback функции. Элементы, добавленные в массив после начала выполнения метода, не будут посещены callback функцией.
- Если существующие элементы массива изменятся, значения, переданные в функцию callback, будут значениями на тот момент времени, когда метод посетит их. Эти методы не делает копию массива перед итерацией.
- thisArg имеет смысл использовать только если callback функция не является стрелочной. Так как все стрелочные функции лексически привязываются к значению this. В этом случае нужно объявить функцию с помощью функциональных выражений или через объявление функций.
Мы рассмотрели общие моменты, теперь рассмотрим каждый метод по отдельности.
forEach
- Выполняет указанную функцию один раз для каждого элемента в массиве.
- Способа остановить или прервать forEach — нет. Однако, можно выбросить и поймать исключение. Если вам необходимо такое поведение, метод forEach() неправильный выбор. Для этого лучше использовать for/for-of с break/continue.
map
- Создаёт новый массив с результатом вызова указанной функции для каждого элемента массива.
filter
- Создаёт новый массив со всеми элементами, которые удовлетворяют условию в callback функции.
- Callback функция должна возвращать булевское значение (или приводимое к нему значение). Текущий обрабатываемый элемент попадет в результирующий массив, если функция вернет true.
- Примеры использования: вывод всех нечетных чисел, вывод строк определенной длины и т.д.
every
- Проверяет, удовлетворяют ли все элементы массива условию, заданному в передаваемой функции (как логическое И).
- Возвращает true если функция проверки возвращает true для каждого элемента массива. Иначе - false.
- Прерывает дальнейшее выполнение, как только найдется первый элемент, для которого callback функция вернет false.
some
- Проверяет, удовлетворяет ли какой-либо элемент массива условию, заданному в callback функции (как логическое ИЛИ).
- Метод возвращает true, если callback функция возвращает true хотя бы для одного элемента массива. Иначе - false.
- Прерывает дальнейшее выполнение, как только найдется первый элемент, для которого callback функция вернет true.
flatMap
- Сначала применяет функцию к каждому элементу, а затем преобразует полученный результат в плоскую структуру с глубиной 1 и помещает в новый массив.
О методах reduce и reduceRight
Таким же образом опишем сначала общие моменты, а далее рассмотрим каждый метод отдельно. Эти методы:
- Принимают два аргумента: callback и initialValue;
- callback (обязательный) — функция, выполняющаяся для каждого элемента массива, принимает четыре аргумента:
accumulator (обязательный) — аккумулирующее значение, которое возвращает функция callback после посещения очередного элемента;
currentValue (обязательный) — текущий обрабатываемый элемент массива;
index (необязательный) — индекс текущего обрабатываемого элемента массива;
array (необязательный) — массив, для которого была вызвана функция reduce. - initialValue (необязательный) — объект, используемый в качестве значения при первом вызове callback функции;
- Если массив пустой и аргумент initialValue не указан, будет брошено исключение TypeError;
- В следующих случаях будет возвращено одно значение без вызова callback функции:
если initialValue не указан и массив состоит только из одного элемента;
если initialValue указан, но массив пустой;
reduce
- Применяет функцию reducer к каждому элементу массива слева-направо, возвращая одно результирующее значение.
- Если initialValue не задан, то значение accumulator будет равным первому значению в массиве, а значение currentValue будет равным второму значению в массиве.
reduceRight
- Применяет функцию reducer к каждому элементу массива справа-налево, возвращая одно результирующее значение.
- Если initialValue не задан, то значение accumulator будет равным последнему элементу в массиве, а значение currentValue будет равным второму с конца элементу в массиве.
Итоги
Мы рассмотрели различные способы обхода массивов и нюансы, связанные с каждым из этих способов: forEach, for/for-of, map, filter, every, some, flatMap, reduce, reduceRight.
Подписывайтесь на нас: