Gdy nie wiesz, ile iteracji potrzebujesz
Pętla for sprawdza się, gdy z góry znasz zakres: „zrób to 10 razy”, „przejdź po każdym indeksie tej tablicy”. Pętla while jest na drugi przypadek: działaj, dopóki coś się nie zmieni. Nie wiesz, ile iteracji to zajmie, znasz tylko warunek, który każe przestać.
Postać jest minimalna:
JavaScript oblicza warunek w nawiasach. Jeśli jest truthy, blok się wykonuje. Potem warunek jest sprawdzany znowu i znowu, aż stanie się falsy. Zapomnisz o count++, a warunek nigdy się nie zmieni: witaj w pętli nieskończonej.
Model myślowy: sprawdź, wykonaj, powtórz
Żeby pętla while miała sens, muszą być spełnione trzy rzeczy:
- Coś, od czego zależy warunek.
- Sposób, w jaki ciało pętli zmienia to coś.
- W końcu warunek staje się fałszywy.
Pomiń którąkolwiek z nich i masz kłopot. Klasyczny błąd to zapomnienie o punkcie 2:
let count = 0;
while (count < 5) {
console.log(count);
// forgot to increment count - loops forever
}
To działa, dopóki nie zabijesz procesu. Na serwerze robi prawdziwe szkody. Zawsze zadaj sobie pytanie: co w ciele pętli sprawi, że warunek stanie się fałszywy?
Prawdziwy przypadek użycia: nieznany punkt zatrzymania
Tu while wygrywa z for. Pobierasz elementy z jakiegoś źródła i nie wiesz, ile ich jest, dopóki ich nie wyczerpiesz:
shift() usuwa i zwraca pierwszy element. Pętla działa, dopóki w kolejce coś jest, i kończy się naturalnie, gdy kolejka jest pusta. Dałoby się to napisać pętlą for, ale walczyłbyś z kształtem problemu, a while czyta się zgodnie z intencją.
do...while: najpierw działaj, potem pytaj
do...while odwraca kolejność: wykonuje ciało, a potem sprawdza warunek. To gwarantuje co najmniej jedną iterację:
Ciało zawsze wykona się raz, nawet jeśli warunek od początku jest fałszywy. Porównaj to ze zwykłym while, gdzie fałszywy warunek oznacza zero iteracji.
Codzienny przypadek: pytasz użytkownika, sprawdzasz odpowiedź i pytasz ponownie, jeśli jest zła. Zawsze chcesz zapytać co najmniej raz, więc do...while pasuje idealnie.
Zwróć uwagę na średnik po zamykającym ): w przeciwieństwie do while i for, do...while go wymaga.
break: wcześniejsze wyjście
break natychmiast kończy najbliższą pętlę. W ten sposób zatrzymujesz się, gdy naturalny warunek nie całkiem pasuje do zadania:
Gdy break się wykona, nic więcej w pętli już nie działa: ani reszta ciała, ani kolejne sprawdzenie warunku. Jesteś poza pętlą.
while (true) z break
Gdy warunek zatrzymania łatwiej wyrazić w ciele niż w nagłówku, odwróć strukturę: kręć pętlą bez końca i wyjdź przez break, gdy skończysz.
Dwa wyjścia: sukces i limit bezpieczeństwa. Limit bezpieczeństwa ma znaczenie. while (true) bez gwarantowanej ścieżki do break to pętla nieskończona, która tylko czeka, żeby się wydarzyć.
continue: przejście do następnej iteracji
continue przeskakuje do kolejnego sprawdzenia warunku, pomijając resztę ciała bieżącej iteracji:
Jedna pułapka: jeśli to, co posuwa pętlę do przodu, stoi po continue, właśnie zbudowałeś pętlę nieskończoną. W przykładzie powyżej n++ jest przed continue, więc wszystko gra. Przenieś je za continue, a n utknie na zawsze na liczbie parzystej.
while czy for: co wybrać
Mechaniczna zasada:
- Liczenie albo indeksowanie znanego zakresu →
for.for (let i = 0; i < arr.length; i++)trzyma inicjalizację licznika, warunek i krok w jednej linii. - Iterowanie po kolekcji →
for...of. Czytelniej niż zarządzanie indeksem. - Pętla do zmiany jakiegoś stanu →
while. Przetwarzanie kolejki, odpytywanie (polling), odczyt strumienia, ponawianie aż do skutku. - Zawsze co najmniej jedno wykonanie →
do...while.
W teorii są wymienne: każdą pętlę for można przepisać na while i odwrotnie. Ale wybór tej, która pasuje do kształtu problemu, sprawia, że kod sam się dokumentuje.
Pętle nieskończone: jedna zasada
Każda pętla while potrzebuje jasnej odpowiedzi na pytanie: co ją zatrzyma?
Albo warunek w nagłówku w końcu stanie się fałszywy, albo jest break, które na pewno się wykona. Jeśli nie umiesz wskazać żadnego z nich, pętla nie jest jeszcze gotowa.
// Źle: warunek nigdy się nie zmienia
let ready = false;
while (!ready) {
console.log("czekam...");
// nic tutaj nie zmienia `ready`
}
// Dobrze: ciało wpływa na warunek
let ready = false;
let checks = 0;
while (!ready) {
checks++;
if (checks >= 3) ready = true;
}
W przeglądarce pętla nieskończona zamraża kartę. W Node obciąża rdzeń procesora do pełna, dopóki nie zabijesz procesu. Warto je wyłapać, zanim trafią na produkcję.
Dalej: for...of i for...in
while obsługuje przypadek „dopóki coś się nie zmieni”. Do przechodzenia po tablicach, stringach i obiektach element po elemencie JavaScript ma dwie kolejne formy pętli, stworzone dokładnie do tego: for...of i for...in. O nich w następnej części.
Najczęściej zadawane pytania
Czym jest pętla while w JavaScript?
Pętla while wykonuje swoje ciało raz po raz, dopóki warunek jest truthy. JavaScript najpierw sprawdza warunek, wykonuje blok, a potem sprawdza go znowu. Jeśli za pierwszym razem warunek jest fałszywy, ciało nie wykona się ani razu.
Czym różni się while od do...while?
while sprawdza warunek przed wykonaniem ciała, więc możliwe jest zero iteracji. do...while najpierw wykonuje ciało, a dopiero potem sprawdza warunek, więc zawsze wykona się co najmniej raz. Używaj do...while, gdy pierwsza iteracja musi się odbyć bezwarunkowo, na przykład przy pytaniu użytkownika o dane.
Jak wyjść z pętli while w JavaScript?
Użyj instrukcji break, żeby natychmiast wyjść z pętli, albo continue, żeby przejść do następnej iteracji. Dzięki break bezpiecznie piszesz pętle while (true): pętla kręci się bez końca, a ty przerywasz ją, gdy w ciele spełni się jakiś warunek.