← Назад к вопросам

Почему нельзя получить длину массива при его переборе?

2.0 Middle🔥 161 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Проблема с изменением длины массива во время итерации

Это классическая ошибка в JavaScript, связанная с тем, как браузер обрабатывает циклы и динамические изменения массива.

Почему так происходит

Проблема возникает, когда вы пытаетесь удалять элементы из массива внутри цикла, полагаясь на свежую длину массива:

// Неправильно - может привести к пропуску элементов
const arr = [1, 2, 3, 4, 5];
for (let i = 0; i < arr.length; i++) {
  console.log(arr[i]); // 1
  arr.splice(i, 1); // Удаляем текущий элемент
  // Теперь arr.length изменилась, но цикл продолжает использовать старое значение
}
// Результат: 1, 3, 5 - элементы 2 и 4 были пропущены!

Причина: когда вы используете arr.length в условии цикла, JavaScript вычисляет значение один раз перед началом цикла. Если вы изменяете массив во время итерации, это не влияет на условие цикла.

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

// Неправильно - бесконечный цикл
const arr = [1, 2, 3];
for (let i = 0; i < arr.length; i++) {
  arr.push(Math.random()); // Увеличиваем длину массива
  console.log(arr[i]); // Цикл никогда не закончится!
}

Если вы используете arr.length в условии и изменяете массив, добавляя элементы, цикл никогда не закончится.

Правильные способы решения

Способ 1: Кешируем длину перед началом цикла

// Правильно - сохраняем исходную длину
const arr = [1, 2, 3, 4, 5];
const length = arr.length;
for (let i = 0; i < length; i++) {
  console.log(arr[i]);
  arr.splice(0, 1); // Удаляем первый элемент
}
// Все элементы обработаны: 1, 2, 3, 4, 5

Способ 2: Итерируем в обратном порядке

// Правильно - идем от конца к началу
const arr = [1, 2, 3, 4, 5];
for (let i = arr.length - 1; i >= 0; i--) {
  if (arr[i] % 2 === 0) { // Удаляем четные
    arr.splice(i, 1);
  }
}
console.log(arr); // [1, 3, 5]

Способ 3: Используем filter вместо мутирования

// Правильно - функциональный подход
const arr = [1, 2, 3, 4, 5];
const filtered = arr.filter(x => x % 2 !== 0);
console.log(filtered); // [1, 3, 5]
// Исходный массив не изменяется

Способ 4: Используем методы, которые отлично работают с изменениями

// Правильно - forEach работает иначе
const arr = [1, 2, 3, 4, 5];
arr.forEach((value, index) => {
  console.log(value);
  // Но будьте осторожны - удаление элементов все еще может вызвать проблемы
  if (value % 2 === 0) {
    arr.splice(index, 1);
  }
});

Лучшие практики

  1. Не мутируйте массив во время итерации - используйте filter, map, reduce вместо splice
  2. Если нужно удалять - итерируйте в обратном порядке
  3. Кешируйте длину - если все же используете цикл with length
  4. Предпочитайте функциональные методы - они безопаснее и понятнее

Почему это важно на собеседовании

Этот вопрос проверяет:

  • Понимание того, как JavaScript обрабатывает циклы
  • Осведомленность о side effects и мутации данных
  • Знание функциональных методов массива
  • Умение писать безопасный, предсказуемый код
Почему нельзя получить длину массива при его переборе? | PrepBro