Метод forEach() используется для перебора массива или объекта. Метод предоставляет нам доступ к отдельным элементам, чтобы мы могли извлекать их, манипулировать ими или каким-либо образом преобразовывать их.

Эта статья была первоначально опубликована в моем блоге, я был бы рад, если бы вы могли посетить меня и подписаться на мою рассылку, пока вы там, чтобы получать регулярные обновления моих новых сообщений!

Как работает метод forEach()?

Структура forEach выглядит следующим образом, я также указал необязательные аргументы для функции.

array.forEach(function(currentValue, index [optional], array [optional]), thisArg[optional])

Метод forEach выполняет цикл по заданному массиву, однако, в отличие от обычного цикла for, он передает функцию обратного вызова для каждого непустого элемента массива. . Давайте еще раз взглянем на синтаксис forEach.

// Lets initialize an array called numbers
let numbers = [1,2,3,4]
numbers.forEach(function(){
 // code
})

Здесь мы видим, что метод forEach принимает функцию обратного вызова. Функция обратного вызова принимает три аргумента. Текущее значение, индекс и сам объект массива.

Текущее значение — это значение на текущей итерации. Это единственный обязательный аргумент, поэтому давайте назовем аргумент как-то семантически правильным. Список чисел будет иметь элементы, называемые числом.

numbers.forEach(function(number){
 // code
})

Теперь мы можем добавить немного логики в функцию. Давайте пока войдем в консоль.

let numbers = [1,2,3,4]
numbers.forEach(function(number){
 console.log(number);
})
// logs 1
// logs 2
// logs 3
// logs 4

Мы также можем определить функции обратного вызова отдельно для метода forEach.

let users = [‘user1’,’user2',’user3']
// A method to use as callback
function findUser(user){
 if(user == ‘user2’) console.log(‘user found’);
}
// Pass the callback into the function
users.forEach(findUser);
// logs user found

Это делает код более читаемым, если логика функции обратного вызова сложна.

А как насчет оставшихся необязательных аргументов?

Показатель

Первым необязательным аргументом функции обратного вызова является индекс. Индекс является представлением текущего номера итерации. Эквивалент переменной i в обычном цикле for.

for(let i =0; i < array.length; i++)

// Example using index.
let names =[‘kate’,’jack’,’john’]
names.forEach(function(name,index){
 console.log(index, name);
})
// logs 0 kate
// logs 1 jack
// logs 2 john

Краткое отступление: обратный вызов forEach как функция стрелки

Я предпочитаю писать функции в виде стрелочных функций. Мы можем заменить функцию обратного вызова функцией стрелки.

array.forEach((element) => {
 console.log(element);
})

thisArg

Этот параметр используется нечасто, но thisArg относится к контексту, в котором должен быть вызван обратный вызов. Если вы не укажете параметр thisArg, контекст, на который ссылается ключевое слово this, станет окном.

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

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

array.forEach(function(item)=>{
 console.log(this === window) // true
 console.log(this === array) //false
})
// add thisArg parameter.
array.forEach(function(item)=>{
 console.log(this === window) //false
 console.log(this == array) //true
}, array)

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

Когда следует использовать forEach вместо цикла for?

1. Метод forEach сохраняет все переменные внутри области действия функции обратного вызова. Переменные вне области действия сохранят свое значение. Ниже мы видим, что переменная name сохраняет область действия блока для функции обратного вызова.

const name = ‘john’
const arrNames = [‘jack’,’jill’,’june’]
arrNames.forEach(function(name){
 console.log(name);
})
// logs john
console.log(name)
// logs name

2. Предотвращает ошибки границ при доступе к элементам путем индексации с использованием цикла for. Если мы хотим выполнить итерацию по списку, но не указали правильный диапазон/ограничение в цикле, мы можем предотвратить это, используя forEach().

let fruits = [‘apple’,’banana’,’orange’];
for(let i = 0; i <= fruits.length ; i++){
 console.log(fruits[i]);
}
// logs apple
// logs banana
// logs orange
// logs undefined (since we stepped out of range)
// forEach implementation
fruits.forEach(function(fruit){
 console.log(fruit);
})
// logs apple
// logs banana
// logs orange

Когда не следует использовать forEach вместо цикла for?

Я использую цикл forEach везде, где это возможно, так как он более лаконичен, чем цикл for. Однако единственный случай, когда следует избегать цикла forEach, — это когда мы хотим выйти из цикла досрочно, используя оператор break, или передать текущую итерацию с помощью continue. заявление.

Например, мы хотим выйти из цикла, когда выполняется какое-то условие поиска.

let conditionalCheck = [1,2,3,null,4,5,6]
for(let i = 0; i < conditionalCheck.legnth; i++){
 if(conditionalCheck[i] == null){
 break;
 } 
 console.log(conditionalCheck[i])
}
// logs 1
// logs 2
// logs 3

Вывод

Этот пост должен предоставить вам информацию, необходимую при принятии решения о том, какой тип цикла использовать. Что касается производительности между двумя циклами, цикл for быстрее по сравнению с циклом forEach. Однако удобочитаемость и ремонтопригодность кодовых баз должны быть приоритетом, который может обеспечить forEach.

Если вы хотите предложить мне темы для обсуждения или хотите поболтать, не стесняйтесь написать мне по электронной почте. Вы можете найти больше таких сообщений на www.colorcoder.dev. Спасибо за чтение! :)