|
На языке JavaScript для завершения вложенных циклов есть несколько способов. Рассмотрим их все — от самых простых до более продвинутых.
1. Использование меток (labels)
Это самый прямой и читаемый способ для завершения именно вложенных циклов.
outerLoop: for (let i = 0; i < 5; i++) { for (let j = 0; j < 5; j++) { if (i === 2 && j === 2) { break outerLoop; // Выход из обоих циклов } console.log(`i=${i}, j=${j}`); }
} // Вывод остановится на i=2, j=2
Метку можно использовать не только с break, но и с continue:
outerLoop: for (let i = 0; i < 3; i++) { for (let j = 0; j < 3; j++) { if (j === 1) { continue outerLoop; // Переход к следующей итерации внешнего цикла } console.log(`i=${i}, j=${j}`); }
} // Вывод: (0,0), (1,0), (2,0)
2. Флаг-переменная (условный выход)
Классический подход без использования меток:
let shouldBreak = false; for (let i = 0; i < 5 && !shouldBreak; i++) { for (let j = 0; j < 5; j++) { if (i === 2 && j === 2) { shouldBreak = true; break; // Выход из внутреннего цикла } console.log(`i=${i}, j=${j}`); }
}
Недостаток: нужно проверять флаг в условии каждого цикла или после внутреннего цикла делать дополнительную проверку.
3. Вынесение в функцию + return
Один из самых чистых способов — обернуть циклы в функцию и использовать return:
function findAndStop() { for (let i = 0; i < 5; i++) { for (let j = 0; j < 5; j++) { if (i === 2 && j === 2) { return; // Выход из функции → завершение всех циклов } console.log(`i=${i}, j=${j}`); } }
}
findAndStop();
Если нужно вернуть значение:
function findValue() { for (let i = 0; i < 5; i++) { for (let j = 0; j < 5; j++) { if (i === 2 && j === 2) { return { i, j }; // Возвращаем результат } } } return null;
}
4. Использование исключений (try/catch)
Не рекомендуется для управления потоком, но технически работает:
try { for (let i = 0; i < 5; i++) { for (let j = 0; j < 5; j++) { if (i === 2 && j === 2) { throw new Error('Break all loops'); } console.log(`i=${i}, j=${j}`); } }
} catch (e) { // Ловим исключение и игнорируем
}
5. Изменение счётчиков (костыльный способ)
Можно искусственно выставить счётчики на значения, завершающие циклы:
for (let i = 0; i < 5; i++) { for (let j = 0; j < 5; j++) { if (i === 2 && j === 2) { i = 5; // Завершаем внешний цикл break; // Выход из внутреннего } console.log(`i=${i}, j=${j}`); }
}
Проблемы: нечитаемо, легко допустить ошибку при сложных условиях.
6. Использование .some() или .every() для массивов
Если вы итерируете массивы, можно использовать встроенные методы:
const matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9]
];
// Прерываем при нахождении числа 5
matrix.some(row => { return row.some(cell => { if (cell === 5) { return true; // Останавливает оба some() } console.log(cell); return false; });
});
some() останавливается при первом return true.
[Сравнение способов]
| Способ |
Читаемость |
Гибкость |
Производительность |
| 1. Метки |
⭐⭐⭐⭐⭐ |
⭐⭐⭐⭐⭐ |
Отлично |
| 2. Функция + return |
⭐⭐⭐⭐⭐ |
⭐⭐⭐⭐ |
Отлично |
| 3. Флаг |
⭐⭐⭐ |
⭐⭐⭐⭐ |
Хорошо |
| 4. Исключения |
⭐ |
⭐⭐ |
Плохо (дорого) |
| 5. Изменение счётчиков |
⭐ |
⭐ |
Хорошо |
| 6. .some() / .every() |
⭐⭐⭐⭐ |
⭐⭐⭐ (только массивы) |
Хорошо |
Рекомендация: для большинства случаев используйте метки (способ 1) или обёртку в функцию с return (способ 2). Это наиболее читаемые и производительные способы.
// ✅ Предпочтительный вариант
outer: for (let i = 0; i < n; i++) { for (let j = 0; j < m; j++) { if (condition) break outer; }
}
|