Lekcja 5: Pętle

Pętle pozwalają na wielokrotne wykonywanie bloku kodu, dopóki określony warunek jest spełniony lub dla każdego elementu w kolekcji. Są niezbędne do automatyzacji powtarzalnych zadań.

Pętla `for`

Najczęściej używana pętla, idealna, gdy znamy liczbę powtórzeń lub chcemy iterować w określonym zakresie.

for (inicjalizacja; warunek; inkrementacja/dekrementacja) {
    // Kod do wykonania w każdej iteracji
}
// Wyświetlenie liczb od 0 do 4
for (let i = 0; i < 5; i++) {
    console.log("Iteracja numer:", i);
}
// Wynik:
// Iteracja numer: 0
// Iteracja numer: 1
// Iteracja numer: 2
// Iteracja numer: 3
// Iteracja numer: 4

// Iterowanie po tablicy
let kolory = ["czerwony", "zielony", "niebieski"];
for (let i = 0; i < kolory.length; i++) {
    console.log("Kolor:", kolory[i]);
}
// Wynik:
// Kolor: czerwony
// Kolor: zielony
// Kolor: niebieski

Pętla `while`

Wykonuje blok kodu tak długo, jak długo podany warunek jest prawdziwy. Warunek jest sprawdzany przed każdą iteracją.

while (warunek) {
    // Kod do wykonania
    // Ważne: Należy pamiętać o modyfikacji zmiennej warunkowej, aby uniknąć pętli nieskończonej!
}
let i = 0;
while (i < 3) {
    console.log("Pętla while, iteracja:", i);
    i++; // Bez tego mielibyśmy pętlę nieskończoną!
}
// Wynik:
// Pętla while, iteracja: 0
// Pętla while, iteracja: 1
// Pętla while, iteracja: 2

Pętla `do...while`

Podobna do `while`, ale warunek jest sprawdzany po wykonaniu bloku kodu. Oznacza to, że blok kodu wykona się przynajmniej raz, nawet jeśli warunek jest od początku fałszywy.

do {
    // Kod do wykonania
    // Pamiętaj o modyfikacji zmiennej warunkowej!
} while (warunek);
let j = 5;
do {
    console.log("Pętla do...while, iteracja:", j);
    j++;
} while (j < 3); // Warunek jest fałszywy od początku
// Wynik:
// Pętla do...while, iteracja: 5 (wykonało się raz)

Pętla `for...of` (ES6)

Służy do iterowania po iterowalnych obiektach, takich jak tablice, stringi, mapy, sety itp. W każdej iteracji dostajemy kolejną wartość z kolekcji.

for (const element of kolekcja) {
    // Kod do wykonania dla każdego elementu
}
// Iterowanie po tablicy
let owoce = ["jabłko", "banan", "pomarańcza"];
for (const owoc of owoce) {
    console.log("Owoc:", owoc);
}
// Wynik:
// Owoc: jabłko
// Owoc: banan
// Owoc: pomarańcza

// Iterowanie po stringu
let tekst = "ABC";
for (const litera of tekst) {
    console.log("Litera:", litera);
}
// Wynik:
// Litera: A
// Litera: B
// Litera: C

Pętla `for...in`

Służy do iterowania po właściwościach obiektu (kluczach).

for (const klucz in obiekt) {
    // Kod do wykonania dla każdego klucza
    // Aby uzyskać wartość: obiekt[klucz]
}
let osoba = {
    imie: "Jan",
    nazwisko: "Kowalski",
    wiek: 30
};

for (const klucz in osoba) {
    console.log(`${klucz}: ${osoba[klucz]}`);
}
// Wynik (kolejność nie jest gwarantowana):
// imie: Jan
// nazwisko: Kowalski
// wiek: 30

Uwaga: Pętla `for...in` iteruje również po właściwościach dziedziczonych z prototypu. Zazwyczaj nie jest zalecana do iterowania po tablicach (lepiej użyć `for` lub `for...of`).

Instrukcje `break` i `continue`

// Przykład break
for (let i = 0; i < 10; i++) {
    if (i === 5) {
        console.log("Przerywam pętlę przy i = 5");
        break; // Zakończ pętlę
    }
    console.log("Iteracja (break):", i);
}
// Wynik: 0, 1, 2, 3, 4, "Przerywam..."

// Przykład continue
for (let i = 0; i < 5; i++) {
    if (i === 2) {
        console.log("Pomijam iterację dla i = 2");
        continue; // Przejdź do następnej iteracji
    }
    console.log("Iteracja (continue):", i);
}
// Wynik: 0, 1, "Pomijam...", 3, 4

Zadanie praktyczne

Napisz skrypt używający pętli `for`, który oblicza sumę liczb od 1 do 10. Wyświetl wynik w konsoli.

Pokaż rozwiązanie
let suma = 0;

for (let i = 1; i <= 10; i++) {
    suma += i; // Dodaj bieżącą liczbę do sumy
}

console.log("Suma liczb od 1 do 10 wynosi:", suma); // Wynik: 55

Zadanie do samodzielnego wykonania

Dana jest tablica liczb: let liczby = [2, 5, -3, 10, 0, 8, -1];. Użyj pętli `for...of` oraz instrukcji `continue`, aby obliczyć sumę tylko dodatnich liczb z tej tablicy. Wyświetl wynik w konsoli.

FAQ - Pętle

Której pętli używać: `for`, `while` czy `do...while`?

Używaj `for`, gdy znasz liczbę iteracji lub potrzebujesz licznika. Używaj `while`, gdy warunek kontynuacji jest ważniejszy niż liczba iteracji i może być fałszywy na starcie. Używaj `do...while`, gdy chcesz, aby kod wykonał się przynajmniej raz, niezależnie od warunku.

Jaka jest różnica między `for...of` a `for...in`?

`for...of` iteruje po wartościach w iterowalnych obiektach (jak tablice, stringi). `for...in` iteruje po kluczach (nazwach właściwości) obiektu. Do iteracji po tablicach zazwyczaj preferuje się `for...of` lub metody tablicowe (np. `forEach`).

Jak uniknąć pętli nieskończonej?

W pętlach `while` i `do...while` upewnij się, że warunek pętli w pewnym momencie stanie się fałszywy. Zazwyczaj oznacza to modyfikowanie zmiennej używanej w warunku wewnątrz ciała pętli (np. przez inkrementację licznika).

Czy mogę używać `break` i `continue` we wszystkich pętlach?

Tak, instrukcje `break` i `continue` działają we wszystkich typach pętli (`for`, `while`, `do...while`, `for...of`, `for...in`). Pamiętaj, że `break` przerywa całą pętlę, a `continue` tylko bieżącą iterację.

Czy pętle mogą być zagnieżdżane?

Tak, można umieszczać pętle wewnątrz innych pętli. Jest to często używane np. do przetwarzania danych dwuwymiarowych (jak tablice tablic) lub generowania wzorów. Należy jednak uważać na wydajność przy głębokim zagnieżdżaniu.

Czy `for...of` działa na obiektach?

Standardowe obiekty JavaScript nie są iterowalne w sensie pętli `for...of`. Aby iterować po właściwościach obiektu, użyj pętli `for...in` lub metod takich jak `Object.keys()`, `Object.values()`, `Object.entries()` w połączeniu z `for...of`.