$ sudo teach IT
МОДУЛЬ 4 · УРОК 3

break и continue: управляй ходом цикла

Иногда нужно не просто «выполни N раз», а «выполняй, пока не найдёшь нужное — и сразу стоп». Или «выполняй каждый раз, но пропускай некоторые». Именно для этого в JavaScript есть два оператора: break (немедленный выход из цикла) и continue (пропуск текущей итерации).

⏱ ~20 минут 🎓 Для новичков 🟨 JavaScript

🛑 break: немедленный выход из цикла

Оператор break делает одну простую вещь: мгновенно прекращает выполнение цикла и переходит к коду, идущему после него. Неважно, на каком шаге мы находимся — цикл просто останавливается.

for (let i = 1; i <= 10; i++) {
  if (i === 5) {
    break; // выходим из цикла, когда i равно 5
  }
  console.log(i);
}
console.log("Цикл завершён");

// Результат:
// 1
// 2
// 3
// 4
// Цикл завершён    ← 5 не выводится, мы вышли раньше

Когда i стало равно 5, сработал break. Мы вышли из цикла, не дожидаясь конца (до 10). Число 5 не вывелось, потому что break стоит до console.log.

🔑 break выходит из цикла целиком. Код после тела цикла (после }) продолжает выполняться.

⏭️ continue: пропуск итерации

Оператор continue делает другое: прерывает текущую итерацию и переходит к следующей. Цикл не останавливается — он продолжает работу, просто пропускает оставшийся код этой конкретной итерации.

for (let i = 1; i <= 10; i++) {
  if (i === 5) {
    continue; // пропускаем итерацию, когда i равно 5
  }
  console.log(i);
}

// Результат:
// 1
// 2
// 3
// 4
// (5 пропущено)
// 6
// 7
// 8
// 9
// 10

Когда i = 5 — сработал continue. Выполнение прыгнуло к шагу i++, потом к условию i <= 10, потом снова в тело — уже с i = 6. Цифра 5 пропущена, но всё остальное работает нормально.

🔑 continue пропускает только текущую итерацию. Цикл продолжается дальше в обычном режиме.

👁️ Разница на одном примере

Посмотрим на одну и ту же задачу, решённую через break и continue, чтобы почувствовать разницу:

break — выход при i=5
for (let i = 1; i <= 8; i++) {
  if (i === 5) break;
  console.log(i);
}
// Вывод:
// 1 2 3 4
// Дальше — тишина

Цикл полностью остановлен на 5. Числа 5–8 не будут обработаны никогда.

continue — пропуск i=5
for (let i = 1; i <= 8; i++) {
  if (i === 5) continue;
  console.log(i);
}
// Вывод:
// 1 2 3 4 6 7 8
// 5 пропущено, всё остальное ок

Число 5 пропущено, но цикл продолжается. Числа 6, 7, 8 обрабатываются.

Аналогия из жизни:

Вы проверяете каждое яблоко в ящике.
break — нашли гнилое яблоко, бросили весь ящик и ушли.
continue — нашли гнилое, выбросили его и продолжили проверять остальные.

🔍 Реальный кейс break: поиск элемента

break особенно полезен при поиске. Как только нашли — незачем продолжать перебор. Это экономит время:

const names = ["Анна", "Борис", "Вика", "Гриша", "Даша"];
const target = "Вика";
let foundIndex = -1; // -1 означает "не найдено"

for (let i = 0; i < names.length; i++) {
  if (names[i] === target) {
    foundIndex = i;
    break; // нашли — нет смысла продолжать!
  }
}

if (foundIndex !== -1) {
  console.log(`Нашли "${target}" по индексу ${foundIndex}`);
} else {
  console.log(`"${target}" не найдено`);
}

// Нашли "Вика" по индексу 2

Без break цикл продолжил бы проверять «Гришу» и «Дашу» — хотя результат уже известен. В массиве из миллиона элементов это может быть существенной разницей в скорости.

Ещё один пример: проверяем, есть ли в массиве отрицательное число. Как только нашли — ответ уже известен:

const numbers = [5, 12, 8, -3, 6, 7];
let hasNegative = false;

for (let i = 0; i < numbers.length; i++) {
  if (numbers[i] < 0) {
    hasNegative = true;
    break; // нашли отрицательное — больше проверять не нужно
  }
}

console.log("Есть отрицательные числа?", hasNegative); // true

🧹 Реальный кейс continue: фильтрация

continue удобен для «пропускай плохое, обрабатывай хорошее». Классический пример — суммируем только положительные числа, отрицательные игнорируем:

const numbers = [3, -7, 5, -2, 8, -1, 4];
let sum = 0;

for (let i = 0; i < numbers.length; i++) {
  if (numbers[i] < 0) {
    continue; // отрицательное — пропускаем
  }
  sum += numbers[i]; // добавляем только положительные
}

console.log("Сумма положительных:", sum); // 3 + 5 + 8 + 4 = 20

Можно было написать то же самое через if без continue:

// Тот же результат, без continue:
for (let i = 0; i < numbers.length; i++) {
  if (numbers[i] >= 0) {
    sum += numbers[i];
  }
}

Какой вариант лучше? Это вопрос вкуса. Но continue бывает особенно читаем, когда в теле цикла много кода — «пропусти плохой случай в начале, не оборачивай всё в if».

Ещё пример с continue — выводим строки без пустых:

const lines = ["Привет", "", "Как дела", "", "Отлично"];

for (let i = 0; i < lines.length; i++) {
  if (lines[i] === "") {
    continue; // пропускаем пустые строки
  }
  console.log(lines[i]);
}
// Привет
// Как дела
// Отлично

⚙️ break и continue в цикле while

break и continue работают в любом цикле — не только в for, но и в while и do-while. Но с continue в while есть важный нюанс: убедитесь, что счётчик обновляется до continue, иначе получится бесконечный цикл!

🚨 Ловушка: бесконечный цикл с continue в while!

let i = 0;
while (i < 10) {
  if (i === 5) {
    continue; // БЕСКОНЕЧНЫЙ ЦИКЛ! i никогда не меняется
  }
  console.log(i);
  i++; // этот код никогда не достигается при i=5
}

Правильный вариант — обновить i перед continue:

let i = 0;
while (i < 10) {
  i++; // обновляем СНАЧАЛА
  if (i === 5) {
    continue; // теперь безопасно — i уже обновлено
  }
  console.log(i);
}
// 1 2 3 4 6 7 8 9 10

В цикле for этой проблемы нет — шаг (i++) в заголовке выполняется автоматически даже при continue.

🧹 Предупреждение: не злоупотребляйте

break и continue — полезные инструменты, но когда их слишком много, код становится трудно читаемым. Вот плохой пример:

// Плохо: три break и два continue — никто не поймёт логику
for (let i = 0; i < 20; i++) {
  if (i === 3) continue;
  if (i === 7) continue;
  if (i === 10) break;
  if (i === 15) break;
  if (i % 2 === 0) continue;
  console.log(i);
}
// Что это делает? Непонятно без трассировки

Лучше переписать так, чтобы логика была явной:

// Хорошо: одно понятное условие
for (let i = 0; i < 10; i++) {
  if (i % 2 !== 0 && i !== 3 && i !== 7) {
    console.log(i);
  }
}

💡 Правило: один break или continue в цикле — это нормально. Если их несколько — подумайте, можно ли переписать условие так, чтобы обойтись без них. Код должен быть понятен с первого прочтения.

Особенно «горячая» тема у опытных разработчиков — это break в середине цикла «потому что нашли». Альтернатива: выделить поиск в отдельную функцию и вернуть результат через return. Но это тема, когда мы дойдём до функций глубже.

✅ Итоги урока

  • break — немедленно выходит из цикла целиком. Код после цикла продолжается.
  • continue — прерывает текущую итерацию и переходит к следующей. Цикл продолжается.
  • break полезен для поиска: нашли нужное — нет смысла перебирать дальше
  • continue полезен для фильтрации: пропустить «плохие» значения, обработать «хорошие»
  • В while с continue — убедитесь, что счётчик обновляется до continue
  • В for шаг выполняется автоматически даже при continue — безопаснее
  • Не злоупотребляйте: много break/continue в одном цикле делают код нечитаемым

В следующем уроке разберём вложенные циклы подробнее — как они работают с матрицами и почему могут быть медленными. 🚀

Тест по break и continue

7 вопросов

Поиск первого элемента больше порога

Напишите функцию findFirstGreater(arr, threshold), которая принимает массив чисел и пороговое значение, и возвращает первый элемент массива, который больше threshold. Если такого нет — верните null. Используйте break для остановки цикла при нахождении.

Сумма положительных чисел

Напишите функцию sumPositive(arr), которая принимает массив чисел и возвращает сумму только положительных элементов, пропуская отрицательные с помощью continue.