Skip to main content

Оператор label

Оператор label (мітка) дає ім'я блоку коду або циклу, щоб потім керувати виконанням через break чи continue, вказуючи, який саме цикл перервати або продовжити. Це рідкісний і маловживаний інструмент JavaScript, який має сенс майже виключно у вкладених циклах.

Теорія

TL;DR

  • Мітка це ім'я, яке ставлять перед блоком або циклом: outer: for (...) { ... }.
  • break outer перериває позначений цикл цілком, а не лише внутрішній.
  • continue outer пропускає поточну ітерацію позначеного зовнішнього циклу.
  • Мітки не створюють нової області видимості і не є аналогом goto.
  • Код з мітками зазвичай гірше читається, тому їх беруть лише тоді, коли інакше вийти з вкладених циклів незручно.

Швидкий приклад

javascript
outer: for (let i = 0; i < 3; i++) { for (let j = 0; j < 3; j++) { if (i === 1 && j === 1) break outer; console.log(`i = ${i}, j = ${j}`); } }

Результат:

i = 0, j = 0 i = 0, j = 1 i = 0, j = 2 i = 1, j = 0

Синтаксис

Мітку можна поставити перед звичайним блоком:

javascript
labelName: { // інструкції }

Але найчастіше її ставлять перед циклом:

javascript
labelName: for (let i = 0; i < 5; i++) { // тіло циклу }

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

Навіщо потрібна мітка: вихід із вкладених циклів

Зазвичай мітку беруть тоді, коли є вкладені цикли і треба вийти не лише з внутрішнього, а одразу з зовнішнього. Без міток break і continue впливають тільки на найближчий цикл.

Приклад без мітки:

javascript
for (let i = 0; i < 3; i++) { for (let j = 0; j < 3; j++) { if (i === 1 && j === 1) break; console.log(`i = ${i}, j = ${j}`); } }

Результат:

i = 0, j = 0 i = 0, j = 1 i = 0, j = 2 i = 1, j = 0 i = 2, j = 0 i = 2, j = 1 i = 2, j = 2

Тут break зупиняє лише внутрішній цикл, а зовнішній (i) спокійно йде далі, до i = 2.

Приклад з міткою:

javascript
outerLoop: // мітка для зовнішнього циклу for (let i = 0; i < 3; i++) { for (let j = 0; j < 3; j++) { if (i === 1 && j === 1) break outerLoop; console.log(`i = ${i}, j = ${j}`); } }

Результат:

i = 0, j = 0 i = 0, j = 1 i = 0, j = 2 i = 1, j = 0

Тепер break outerLoop перериває весь зовнішній цикл, а не лише внутрішній.

continue з міткою

Так само можна пропустити ітерацію зовнішнього циклу, якщо виконується умова:

javascript
outer: for (let i = 0; i < 3; i++) { for (let j = 0; j < 3; j++) { if (j === 2) continue outer; // пропускає поточний i console.log(`i = ${i}, j = ${j}`); } }

Результат:

i = 0, j = 0 i = 0, j = 1 i = 1, j = 0 i = 1, j = 1 i = 2, j = 0 i = 2, j = 1

Щойно j доходить до 2, керування переходить до наступної ітерації зовнішнього циклу.

Що важливо пам'ятати

Що робитьПриклад
Дає ім'я циклу або блокуouter: for (...) { ... }
Дозволяє вийти з зовнішнього циклуbreak outer;
Дозволяє пропустити ітерацію зовнішнього циклуcontinue outer;
Створює нову область видимостіНі
Використовувати часто?Ні, лише за потреби

Додатково:

  • Мітки не створюють нових областей видимості, це просто імена, до яких звертаються break і continue.
  • Мітку не можна використати для довільних переходів, як goto в інших мовах (наприклад, у C).
  • continue з міткою працює тільки з циклами, тоді як break з міткою працює і з міченим блоком.

Типові помилки

  • Сприймати мітку як goto. Стрибнути вперед або назад у довільне місце не можна: дозволено лише вийти з поміченої конструкції або перейти до її наступної ітерації.
  • Ставити continue з міткою на звичайному блоці. Це синтаксична помилка, continue вимагає, щоб мітка стояла на циклі.
  • Використовувати мітку там, де достатньо функції. Часто винесення вкладених циклів в окрему функцію і звичайний return читається краще, ніж break outer.
  • Плутати мітку з оголошенням змінної. outer: це не змінна, звертатися до неї як до значення не можна.
  • Зловживати мітками. Вони рідкісні саме тому, що ускладнюють читання; беріть їх лише тоді, коли альтернатива виходить громіздкою.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.