Pętle for i while

Pętlę w programowaniu pozwalają nam wykonywać dany kod zadaną ilość razy.

Przypuśćmy, że byliśmy niegrzeczni i nauczyciel kazał nam napisać jakieś zdanie 100 razy. Możemy to oczywiście zrobić za pomocą poniższego kodu:

console.log("Nie będę rozmawiał na lekcji Informatyki.");
console.log("Nie będę rozmawiał na lekcji Informatyki.");
console.log("Nie będę rozmawiał na lekcji Informatyki.");
console.log("Nie będę rozmawiał na lekcji Informatyki.");
console.log("Nie będę rozmawiał na lekcji Informatyki.");
...

Ale o wiele lepiej jest skorzystać z pętli, która wykona dany kod zadaną liczbę razy.

Poniżej zajmiemy się klasycznymi pętlami, które istnieją w większości języków - w tym w Javascript.

Pętla typu for

Jednym z najczęściej stosowanych typów pętli jest instrukcja for.

for (zainicjowanie_zmiennych;  warunek_kończący_wykonywanie_pętli;  zmiana_zmiennych) {
    kod który zostanie wykonany pewną ilość razy
}

Pętle takie najczęściej stosuje się w sytuacjach, kiedy dokładnie znamy liczbę powtórzeń - od - do:

//pętla od 0 do 99
for (let i=0; i<100; i++) {
    console.log("Nie będę rozmawiał na lekcji Informatyki.");
}

W każdej pętli mamy dostęp do jej licznika:

Pętle spokojnie mogą odliczać w przeciwnym kierunku:

A sam warunek kończący wcale nie musi wyglądać jak powyżej:

Jeżeli nie potrzeba, to możemy pominąć dowolną z trzech składowych pętli. Nie używasz licznika? Nie deklarujemy zmiennych. Nie potrzebujesz kończącego warunku? Nie twórz go.

Tak naprawdę nic nie musimy tutaj podawać, a sama pętla może mieć postać:

Widziałem to tylko w jednym miejscu w Internecie - w dokumentacji MDN. Pętla taka staje się nieskończoną pętlą. Na co dzień polecam jednak podawać wszystkie składowe. Czytelność i jasność kodu znacząco się powiększa.

Pętla typu while

Pętla while (dopóki) to kolejny typ pętli, który można spotkać w wielu językach. Struktura tej pętli ma następującą postać:

Zauważ, że w pętli tego typu nie definiujemy ani początkowego licznika, ani nie definiujemy zmiany licznika. Musimy te rzeczy zrobić ręcznie:

Jeżeli w powyższym kodzie pętli nie zwiększalibyśmy zmiennej i, wówczas pętla ta wykonywała by się w nieskończoność (infinite loop), co zaowocowało by "zawieszeniem" strony.

Pętlę while zazwyczaj stosuje się w sytuacjach, kiedy nie wiemy dokładnie, ile iteracji (powtórzeń) ma się wykonać. Wyobraź sobie, że chcesz wygenerować unikalny numer ID albo jakąś liczbę. Generujesz więc daną rzecz, następnie sprawdzasz czy wynik pasuje do założeń. Jak nie pasuje, generujesz dalej. I tak do skutku aż trafisz.

Istnieje też nieco inny wariant pętli while:

Pętla w pętli

Czasami musimy wykonać zadania "n - wymiarowe". Dla przykładu przy wypisywaniu tabliczki mnożenia musimy utworzyć 10 kolumn z 10 komórkami. Do takich działań stosujemy pętle w pętlach.

W powyższych przykładach wykonywaliśmy najczęściej tylko jedno console.log(). Ale przecież takich linii kodu, które mają się powtarzać może być dowolnie wiele. Co więcej - wśród tych linii mogą być zagnieżdżone pętle, które przy każdym przebiegu głównej pętli wykonają swój kod naście razy.

Działanie powyższego skryptu ma postać:

Jak widzisz główna pętla zaczyna działać wykonując po kolei kolejne linie kodu. Wypisuje więc w konsoli jedną czerwoną linijkę. Kod dochodzi do wewnętrznej pętli. Ta zaczyna działać.

Po jej zakończeniu kończy się działanie jednej iteracji głównej pętli. Rozpoczyna się druga iteracja...

Co ważne, wewnętrzne pętle mają dostęp do liczników pętli zewnętrznych.

Bardzo ważne jest by pętle wewnętrzne miały inny licznik niż główna pętla. W przypadku stosowania zmiennych var użycie takiego samego licznika praktycznie zawsze oznacza zawieszenie strony. W przypadku let można niby użyć licznik o takiej samej nazwie, ale tracimy wtedy dodatkowe możliwości:

Przykłady użycia pętli

Powiedzmy, że chcemy w konsoli wypisać tekst:

******

Wykorzystajmy do tego pętlę:

Dodajemy kolejny poziom skomplikowania. Załóżmy, że chcemy wypisać w konsoli poniższy tekst:

****** ****** ****** ******

Użyjmy do tego pętli w pętli:

Pozostaje poziom hard. Załóżmy że chcemy w konsoli wypisać:

****** *----* *----* ******

Użyjmy do tego pętli w pętli, w której zbadamy dane liczniki:

Break i continue

Czasami podczas pętli gdy wykonamy jakąś czynność - czy to wypiszemy dany element, czy go sprawdzimy, chcielibyśmy zakończyć dalsze wykonywanie takiej pętli. Służy do tego instrukcja break.

Drugą instrukcją jest continue. Nie przerywa ona działania pętli, a powoduje przerwanie danej iteracji (czyli aktualnego powtórzenia):

Zwróć uwagę, że gdy stosujemy continue w pętli while, zwiększanie licznika musimy robić przed użyciem tej instrukcji. Inaczej możemy trafić na moment, gdy aktualne powtórzenie będzie przerywane a tym samym zwiększanie licznika nigdy nie nastąpi.

Labele dla pętli

Każda pętla może być dodatkowo nazwana za pomocą etykiet. Dzięki nim możemy stosować instrukcje break i continue dla pętli o danej nazwie:

Przy czym funkcjonalność ta jest tak skrajnie rzadko używana, że prawdopodobnie nigdy się z nią nie zetkniesz...

Edit: Tak naprawdę składnia ta zyskuje na popularności za sprawą https://svelte.dev/, który używa jej oznaczania reaktywnych deklaracji:

Last updated