Domů O mně Služby Portfolio Učím Blog Kontakt
← Zpět na učím

2.9 Break a continue

Výuka

Proč potřebujeme řízení cyklů?

Někdy chceš:

  • Ukončit cyklus předčasně - našel jsi, co jsi hledal
  • Přeskočit některé iterace - nechceš zpracovat určité prvky

K tomu slouží break a continue.

break - okamžité ukončení cyklu

for (let i = 0; i < 10; i++) {
  if (i === 5) {
    break;  // Ukončí cyklus
  }
  console.log(i);
}
// 0, 1, 2, 3, 4 (5 a dále se nevypíše)

break okamžitě vyskočí z nejbližšího obklopujícího cyklu.

continue - přeskočení na další iteraci

for (let i = 0; i < 5; i++) {
  if (i === 2) {
    continue;  // Přeskočí zbytek iterace
  }
  console.log(i);
}
// 0, 1, 3, 4 (2 se přeskočí)

continue přeskočí zbytek aktuální iterace a pokračuje další iterací.

Vizuální rozdíl

for (i = 0; i < 5; i++) {
  if (i === 2) break;       0, 1         (KONEC)
  console.log(i);
}

for (i = 0; i < 5; i++) {
  if (i === 2) continue;    0, 1, 3, 4   (přeskočí 2)
  console.log(i);
}

JavaScript

// break - najdi první sudé číslo
const numbers = [1, 3, 5, 4, 7, 8];

for (const num of numbers) {
  if (num % 2 === 0) {
    console.log(`První sudé: ${num}`);
    break;
  }
}
// "První sudé: 4"

// continue - přeskočení záporných čísel
const values = [1, -2, 3, -4, 5];

for (const val of values) {
  if (val < 0) {
    continue;  // Přeskoč záporná
  }
  console.log(val);
}
// 1, 3, 5

// break ve vnořených cyklech - ukončí jen VNITŘNÍ
for (let i = 0; i < 3; i++) {
  for (let j = 0; j < 3; j++) {
    if (j === 1) break;  // Ukončí jen vnitřní cyklus
    console.log(`i=${i}, j=${j}`);
  }
}
// i=0,j=0 | i=1,j=0 | i=2,j=0

// Labeled break - ukončí VNĚJŠÍ cyklus
outer: for (let i = 0; i < 3; i++) {
  for (let j = 0; j < 3; j++) {
    if (i === 1 && j === 1) {
      break outer;  // Ukončí vnější cyklus
    }
    console.log(`i=${i}, j=${j}`);
  }
}
// i=0,j=0 | i=0,j=1 | i=0,j=2 | i=1,j=0

// Labeled continue
outer: for (let i = 0; i < 3; i++) {
  for (let j = 0; j < 3; j++) {
    if (j === 1) {
      continue outer;  // Přeskočí na další iteraci vnějšího cyklu
    }
    console.log(`i=${i}, j=${j}`);
  }
}

// break v while
let count = 0;

while (true) {  // "Nekonečný" cyklus
  count++;
  if (count >= 5) {
    break;  // Ale má únikovou cestu
  }
}

// break v switch (připomenutí)
switch (day) {
  case "monday":
    console.log("Pondělí");
    break;  // Bez break by propadl do dalšího case
  case "tuesday":
    console.log("Úterý");
    break;
}

// Praktický příklad: hledání v poli
function findUser(users, id) {
  for (const user of users) {
    if (user.id === id) {
      return user;  // return také ukončí cyklus
    }
  }
  return null;
}

// Filtrování s continue
const items = ["", "jablko", null, "banán", undefined, "třešeň"];
const validItems = [];

for (const item of items) {
  if (!item) continue;  // Přeskoč falsy hodnoty
  validItems.push(item);
}
// ["jablko", "banán", "třešeň"]

TypeScript

// break a continue fungují stejně jako v JS
const numbers: number[] = [1, 2, 3, 4, 5];

for (const num of numbers) {
  if (num === 3) break;
  console.log(num);
}

// Typovaná funkce s early return (místo break)
function findFirst<T>(arr: T[], predicate: (item: T) => boolean): T | undefined {
  for (const item of arr) {
    if (predicate(item)) {
      return item;
    }
  }
  return undefined;
}

const found = findFirst([1, 2, 3, 4], n => n > 2);
console.log(found);  // 3

// Type guard s continue
function processItems(items: (string | null | undefined)[]): string[] {
  const result: string[] = [];

  for (const item of items) {
    if (item === null || item === undefined) {
      continue;
    }
    // TypeScript ví, že item je string
    result.push(item.toUpperCase());
  }

  return result;
}

// Labeled statements s typy (zřídka používané)
function searchMatrix(matrix: number[][]): [number, number] | null {
  search: for (let i = 0; i < matrix.length; i++) {
    for (let j = 0; j < matrix[i].length; j++) {
      if (matrix[i][j] === 0) {
        return [i, j];  // Nebo: break search;
      }
    }
  }
  return null;
}

// Validace s continue
interface User {
  name: string;
  email: string;
  age: number;
}

function validateUsers(users: User[]): User[] {
  const valid: User[] = [];

  for (const user of users) {
    if (!user.name) continue;
    if (!user.email.includes("@")) continue;
    if (user.age < 0) continue;

    valid.push(user);
  }

  return valid;
}

Rozdíl JS vs TS

JavaScript TypeScript
break/continue fungují stejně break/continue fungují stejně
Žádná kontrola TS pomáhá s type narrowing po continue
Labels jsou řídké Labels jsou řídké i v TS
// TypeScript narrowing po continue
function process(items: (string | null)[]) {
  for (const item of items) {
    if (item === null) {
      continue;
    }
    // Po continue TS ví, že item je string
    console.log(item.toUpperCase());  // ✅ OK
  }
}

Tip

💡 Preferuj early return před break:

// ❌ S break
function findUser(users, id) {
  let result = null;
  for (const user of users) {
    if (user.id === id) {
      result = user;
      break;
    }
  }
  return result;
}

// ✅ S early return - čitelnější
function findUser(users, id) {
  for (const user of users) {
    if (user.id === id) {
      return user;
    }
  }
  return null;
}

💡 Používej array metody místo continue:

const numbers = [1, -2, 3, -4, 5];

// ❌ S continue
const positive = [];
for (const n of numbers) {
  if (n < 0) continue;
  positive.push(n);
}

// ✅ S filter - deklarativnější
const positive = numbers.filter(n => n >= 0);

💡 Vyhni se labeled statements pokud můžeš:

// ❌ Labels jsou matoucí
outer: for (...) {
  inner: for (...) {
    break outer;
  }
}

// ✅ Extrahuj do funkce
function search() {
  for (...) {
    for (...) {
      if (found) return result;
    }
  }
}

💡 break v switch je POVINNÝ (většinou):

switch (x) {
  case 1:
    doSomething();
    break;  // BEZ tohoto propadne do case 2!
  case 2:
    doOther();
    break;
}

Kvíz

Které výroky jsou pravdivé?

- To dělá continue, ne break. break ukončí cyklus.

- To dělá break, ne continue. continue přeskočí na další iteraci.

- break bez labelu ukončí pouze nejbližší obklopující cyklus

- break label; může ukončit i vnější cyklus označený labelem

🎯 Závěrečný projekt

Po dokončení všech 8 dílů vytvoříte jednoduchou Todо aplikaci v čistém JavaScriptu. Naučíte se, jak aplikovat vše, co jste se naučili, na reálný projekt.

Zobrazit podrobnosti projektu →

Připraveni začít?

Zaregistrujte se a získejte přístup ke všem dílům tohoto seriálu

Kontaktujte mě

Informace o seriálu

Obtížnost

Délka

Cca 480 minut

Počet videí

8 videí + projekty

Certifikát

Po dokončení obdržíte certifikát


Lekce v této sekci


Struktura lekcí (souborový strom)

06. Typescript specifika
  • v přípravě
08. Moduly tridy
  • v přípravě
09. React zaklady
  • v přípravě
10. React hooks
  • v přípravě
12. Nextjs server
  • v přípravě
13. Databaze auth
  • v přípravě
14. Nextjs pokrocile
  • v přípravě