Instrukcją równoważną funkcjonalnie do przedstawionej instrukcji JavaScript jest
for (i = 10; i > 0; i -= 2) document.write(i + ' ');
Kod 1.
i = 10; while (i > 0) { i -= 2; document.write(i + ' '); }
Kod 2.
i = 10; while (i >= 0) { document.write(i + ' '); i -= 2; }
Kod 3.
i = 10; while (i > 0) { document.write(i + ' '); i -= 2; }
Kod 4.
while (i > 0) { document.write(i + ' '); i -= 2; }
A. Kod 4
B. Kod 2
C. Kod 1
D. Kod 3
W tej pętli for najważniejsza jest kolejność działań. Instrukcja for (i = 10; i > 0; i -= 2) najpierw ustawia i na 10, potem sprawdza warunek i > 0, następnie wykonuje document.write(i + ' '), a dopiero po zakończeniu ciała pętli zmniejsza i o 2. Dlatego wypisane zostaną wartości: 10 8 6 4 2. Kod 3 robi dokładnie to samo: przed pętlą ustawia i = 10, w while sprawdza ten sam warunek i > 0, w środku najpierw wypisuje aktualną wartość i, a dopiero potem wykonuje i -= 2. To jest klasyczna zamiana pętli for na while: inicjalizacja przed pętlą, warunek w nawiasie while, a aktualizacja zmiennej sterującej na końcu bloku. Moim zdaniem to bardzo dobre ćwiczenie, bo pokazuje, że w pętlach liczy się nie tylko warunek, ale też dokładne miejsce instrukcji zwiększania albo zmniejszania licznika. W praktycznym JavaScript warto też pamiętać o deklarowaniu zmiennej, np. let i = 10;, bo używanie samego i tworzy lub wykorzystuje zmienną globalną, co jest złą praktyką. Samo document.write też raczej spotyka się w prostych przykładach edukacyjnych; w normalnych projektach częściej modyfikuje się DOM, np. przez textContent albo append.
W pętlach bardzo łatwo pomylić samą wartość startową z kolejnością wykonywania instrukcji. Oryginalna konstrukcja for wypisuje zmienną przed jej zmniejszeniem, bo część i -= 2 wykonywana jest dopiero po przejściu przez ciało pętli. Jeżeli w wersji z while najpierw zmniejszymy i, a dopiero potem użyjemy document.write, wynik przesuwa się o jeden krok: zamiast zacząć od 10, program zacznie wypisywanie od 8, a na końcu pojawi się nawet 0. To już nie jest to samo działanie, mimo że warunek i > 0 wygląda identycznie. Częsty błąd polega właśnie na tym, że ktoś przepisuje elementy pętli for do while, ale nie zachowuje ich naturalnej kolejności wykonania. Równie istotny jest warunek zakończenia. Zmiana i > 0 na i >= 0 powoduje, że pętla dopuści jeszcze wartość 0 do wypisania, więc wynik stanie się dłuższy: 10 8 6 4 2 0. Niby różnica to tylko jeden znak równości, ale w algorytmach takie szczegóły są konkretne i często decydują o poprawności programu. Trzeba też uważać na inicjalizację zmiennej. Wariant bez i = 10 przed pętlą może zadziałać tylko przypadkiem, jeśli wcześniej i miało odpowiednią wartość. Funkcjonalna równoważność oznacza, że kod powinien sam zapewniać ten sam stan początkowy, ten sam warunek, tę samą kolejność wypisywania i tę samą aktualizację licznika. Z mojego doświadczenia najlepiej przy zamianie for na while rozpisać sobie trzy kroki: start licznika, test warunku, instrukcje w ciele oraz aktualizacja na samym końcu. Wtedy mniej rzeczy umyka.