Learn JavaScript

Перебор массива: for, for...of, forEach

Перебор массива - одна из самых частых операций. В JavaScript для этого часто используют:

  • for (классический цикл с индексом)
  • for...of (перебор по значениям)
  • forEach (метод массива)

Все три варианта решают похожие задачи, но подходят для разных ситуаций.

for: когда нужен индекс и контроль

for удобен, когда:

  • нужен индекс элемента;
  • нужно идти с шагом (например, через один элемент);
  • нужен ранний выход (break) или пропуск итерации (continue);
  • нужно изменять массив по индексу.
const nums = [10, 20, 30];

for (let i = 0; i < nums.length; i += 1) {
  console.log(i, nums[i]);
}
// 0 10
// 1 20
// 2 30

Изменение массива по месту

const nums = [1, 2, 3];

for (let i = 0; i < nums.length; i += 1) {
  nums[i] = nums[i] * 2;
}

console.log(nums); // [2, 4, 6]

Ранний выход

const nums = [5, 7, 9, 2, 10];
let foundIndex = -1;

for (let i = 0; i < nums.length; i += 1) {
  if (nums[i] === 2) {
    foundIndex = i;
    break;
  }
}

console.log(foundIndex); // 3

for…of: когда нужен только элемент

for...of перебирает значения. Он читается проще, когда индекс не нужен.

const names = ["Sam", "Alex", "Kim"];

for (const name of names) {
  console.log(name);
}

Индекс тоже можно получить через entries()

const names = ["Sam", "Alex", "Kim"];

for (const [index, value] of names.entries()) {
  console.log(index, value);
}
// 0 "Sam"
// 1 "Alex"
// 2 "Kim"

Нюанс: изменение массива внутри for…of

Переменная цикла содержит значение элемента, а не “ячейку” массива. Поэтому так массив не изменится:

const nums = [1, 2, 3];

for (let n of nums) {
  n = n * 2;
}

console.log(nums); // [1, 2, 3]

Если нужно менять массив, удобнее использовать for по индексам.

forEach: метод массива для “сделать что-то для каждого”

forEach вызывает функцию для каждого элемента. Он удобен, когда:

  • нужен простой проход без break и continue;
  • важна компактность;
  • не нужен результат (в отличие от map, filter и т.п., которые будут дальше).

Синтаксис:

array.forEach((value, index, array) => { ... })

Пример:

const nums = [10, 20, 30];

nums.forEach((value, index) => {
  console.log(index, value);
});

Ограничение: нельзя остановить forEach через break

forEach не поддерживает break и continue. Если нужен ранний выход, лучше использовать for или for...of.

const nums = [5, 7, 9, 2, 10];
let foundIndex = -1;

nums.forEach((value, index) => {
  if (value === 2 && foundIndex === -1) {
    foundIndex = index;
  }
});

console.log(foundIndex); // 3

Этот пример работает, но перебор все равно пройдет по всем элементам.

Что выбрать на практике

Простое правило:

  • for - если нужен индекс, шаг, изменение массива, break/continue.
  • for…of - если нужен чистый перебор значений и код должен читаться проще.
  • forEach - если нужен короткий проход “для каждого” без остановки.

Частые ошибки

1) i <= arr.length

Это дает лишнюю итерацию и undefined:

const items = ["a", "b", "c"];

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

Правильная граница:

const items = ["a", "b", "c"];

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

2) Ожидание break в forEach

Если нужен ранний выход - forEach не подходит. Для поиска до первого совпадения проще:

const nums = [5, 7, 9, 2, 10];
let foundIndex = -1;

for (let i = 0; i < nums.length; i += 1) {
  if (nums[i] === 2) {
    foundIndex = i;
    break;
  }
}

console.log(foundIndex); // 3

Что стоит запомнить

  • for дает максимум контроля: индекс, шаг, break/continue.
  • for...of перебирает значения и читается проще.
  • forEach удобен для “сделать для каждого”, но без break и continue.