Často musíme akce opakovat.
Například výstup zboží ze seznamu jeden po druhém nebo jen spuštění stejného kódu pro každé číslo od 1 do 10.
Smyčky představují způsob, jak opakovat stejný kód vícekrát.
Smyčky for...of a for...inMalé oznámení pro pokročilé čtenáře.
Tento článek se zabývá pouze základními smyčkami:while
, do..while
a for(..;..;..)
.
Pokud jste se dostali k tomuto článku při hledání jiných typů smyček, zde jsou odkazy:
- Podívejte se na…in pro opakování vlastností objektu.
- Viz…of a iterables pro opakování přes pole a iterovatelné objekty.
V opačném případě čtěte dále.
Smyčka „while“
while
smyčka má následující syntaxi:
while (condition) {
// code
// so-called "loop body"
}
Zatímco condition
je pravda, code
z těla smyčky.
Například smyčka pod výstupem i
zatímco i < 3
:
let i = 0;
while (i < 3) { // shows 0, then 1, then 2
alert( i );
i++;
}
Jedno provedení těla smyčky se nazývá iterace . Smyčka ve výše uvedeném příkladu tvoří tři iterace.
Pokud i++
chyběl ve výše uvedeném příkladu, smyčka by se opakovala (teoreticky) navždy. V praxi prohlížeč poskytuje způsoby, jak zastavit takové smyčky, a v JavaScriptu na straně serveru můžeme proces ukončit.
Jakýkoli výraz nebo proměnná může být podmínkou smyčky, nejen porovnání:podmínka je vyhodnocena a převedena na logickou hodnotu pomocí while
.
Například kratší způsob zápisu while (i != 0)
je while (i)
:
let i = 3;
while (i) { // when i becomes 0, the condition becomes falsy, and the loop stops
alert( i );
i--;
}
Pro jednořadé tělo nejsou složené závorky vyžadovány
Pokud má tělo smyčky jeden příkaz, můžeme vynechat složené závorky {…}
:
let i = 3;
while (i) alert(i--);
Smyčka „do...while“
Kontrolu stavu lze přesunout níže tělo smyčky pomocí do..while
syntaxe:
do {
// loop body
} while (condition);
Cyklus nejprve provede tělo, poté zkontroluje podmínku, a pokud je pravdivá, provede ji znovu a znovu.
Například:
let i = 0;
do {
alert( i );
i++;
} while (i < 3);
Tato forma syntaxe by měla být použita pouze v případě, že chcete, aby se tělo smyčky provedlo alespoň jednou bez ohledu na to, zda je podmínka pravdivá. Obvykle je preferován jiný tvar:while(…) {…}
.
Smyčka „for“
for
smyčka je složitější, ale je to také nejčastěji používaná smyčka.
Vypadá to takto:
for (begin; condition; step) {
// ... loop body ...
}
Naučme se význam těchto částí na příkladu. Smyčka níže běží alert(i)
pro i
z 0
až (ale ne včetně) 3
:
for (let i = 0; i < 3; i++) { // shows 0, then 1, then 2
alert(i);
}
Podívejme se na for
výpis po částech:
část | ||
---|---|---|
začít | let i = 0 | Spustí se jednou při vstupu do smyčky. |
podmínka | i < 3 | Kontrolováno před každou iterací smyčky. Pokud je false, smyčka se zastaví. |
tělo | alert(i) | Běží znovu a znovu, dokud je podmínka pravdivá. |
krok | i++ | Spustí se po těle při každé iteraci. |
Algoritmus obecné smyčky funguje takto:
Run begin
→ (if condition → run body and run step)
→ (if condition → run body and run step)
→ (if condition → run body and run step)
→ ...
To znamená begin
provede se jednou a poté se opakuje:po každém condition
test, body
a step
jsou provedeny.
Pokud jste se smyčkami nováčkem, mohlo by vám pomoci vrátit se k příkladu a zopakovat si, jak to běží, krok za krokem na kus papíru.
Zde je přesně to, co se stane v našem případě:
// for (let i = 0; i < 3; i++) alert(i)
// run begin
let i = 0
// if condition → run body and run step
if (i < 3) { alert(i); i++ }
// if condition → run body and run step
if (i < 3) { alert(i); i++ }
// if condition → run body and run step
if (i < 3) { alert(i); i++ }
// ...finish, because now i == 3
Inline deklarace proměnné
Zde je proměnná „počítadla“ i
je deklarován přímo ve smyčce. Toto se nazývá „inline“ deklarace proměnné. Takové proměnné jsou viditelné pouze uvnitř smyčky.
for (let i = 0; i < 3; i++) {
alert(i); // 0, 1, 2
}
alert(i); // error, no such variable
Místo definování proměnné bychom mohli použít existující:
let i = 0;
for (i = 0; i < 3; i++) { // use an existing variable
alert(i); // 0, 1, 2
}
alert(i); // 3, visible, because declared outside of the loop
Přeskočení částí
Jakákoli část for
lze přeskočit.
Můžeme například vynechat begin
pokud na začátku smyčky nepotřebujeme nic dělat.
Jako zde:
let i = 0; // we have i already declared and assigned
for (; i < 3; i++) { // no need for "begin"
alert( i ); // 0, 1, 2
}
Můžeme také odstranit step
část:
let i = 0;
for (; i < 3;) {
alert( i++ );
}
Díky tomu je smyčka identická s while (i < 3)
.
Můžeme vlastně odstranit všechno a vytvořit tak nekonečnou smyčku:
for (;;) {
// repeats without limits
}
Vezměte prosím na vědomí, že dva for
středníky ;
musí být přítomen. Jinak by došlo k chybě syntaxe.
Přerušení smyčky
Normálně se smyčka ukončí, když se její stav stane chybným.
Můžeme však kdykoli vynutit ukončení pomocí speciálního break
směrnice.
Například smyčka níže žádá uživatele o řadu čísel, která se „přeruší“, když není zadáno žádné číslo:
let sum = 0;
while (true) {
let value = +prompt("Enter a number", '');
if (!value) break; // (*)
sum += value;
}
alert( 'Sum: ' + sum );
break
direktiva je aktivována na řádku (*)
pokud uživatel zadá prázdný řádek nebo zruší zadání. Okamžitě zastaví smyčku a předá řízení prvnímu řádku za smyčkou. Konkrétně alert
.
Kombinace „nekonečná smyčka + break
podle potřeby“ je skvělé pro situace, kdy je nutné zkontrolovat stav smyčky ne na začátku nebo na konci smyčky, ale uprostřed nebo dokonce na několika místech jejího těla.
Pokračovat na další iteraci
continue
direktiva je „odlehčenou verzí“ break
. Nezastaví celou smyčku. Místo toho zastaví aktuální iteraci a vynutí smyčku, aby zahájila novou (pokud to podmínka umožňuje).
Můžeme ji použít, pokud jsme s aktuální iterací hotovi a chtěli bychom přejít k další.
Smyčka níže používá continue
pro výstup pouze liché hodnoty:
for (let i = 0; i < 10; i++) {
// if true, skip the remaining part of the body
if (i % 2 == 0) continue;
alert(i); // 1, then 3, 5, 7, 9
}
Pro sudé hodnoty i
, continue
direktiva zastaví provádění těla a předá řízení další iteraci for
(s dalším číslem). Takže alert
je voláno pouze pro liché hodnoty.
continue
direktiva pomáhá snížit vnořování Smyčka, která ukazuje liché hodnoty, může vypadat takto:
for (let i = 0; i < 10; i++) {
if (i % 2) {
alert( i );
}
}
Z technického hlediska je to totožné s příkladem výše. Jistě, můžeme jen zabalit kód do if
blok místo použití continue
.
Ale jako vedlejší efekt to vytvořilo další úroveň vnoření (alert
volání uvnitř složených závorek). Pokud je kód uvnitř if
je delší než několik řádků, což může snížit celkovou čitelnost.
break/continue
napravo od ‚?‘
Vezměte prosím na vědomí, že konstrukce syntaxe, které nejsou výrazy, nelze použít s ternárním operátorem ?
. Zejména direktivy jako break/continue
tam nejsou povoleny.
Vezmeme-li například tento kód:
if (i > 5) {
alert(i);
} else {
continue;
}
…a přepište jej pomocí otazníku:
(i > 5) ? alert(i) : continue; // continue isn't allowed here
…přestane fungovat:došlo k chybě syntaxe.
To je jen další důvod, proč nepoužívat operátor s otazníkem ?
místo if
.
Štítky pro přerušení/pokračování
Někdy se potřebujeme vymanit z více vnořených smyček najednou.
Například v níže uvedeném kódu procházíme smyčkou i
a j
s výzvou k zadání souřadnic (i, j)
od (0,0)
na (2,2)
:
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
let input = prompt(`Value at coords (${i},${j})`, '');
// what if we want to exit from here to Done (below)?
}
}
alert('Done!');
Potřebujeme způsob, jak zastavit proces, pokud uživatel zruší vstup.
Obyčejný break
po input
pouze by přerušil vnitřní smyčku. To nestačí – štítky, přijďte na pomoc!
štítek je identifikátor s dvojtečkou před smyčkou:
labelName: for (...) {
...
}
break <labelName>
příkaz ve smyčce níže se rozdělí na štítek:
outer: for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
let input = prompt(`Value at coords (${i},${j})`, '');
// if an empty string or canceled, then break out of both loops
if (!input) break outer; // (*)
// do something with the value...
}
}
alert('Done!');
Ve výše uvedeném kódu break outer
hledá štítek s názvem outer
směrem nahoru a vypadne z této smyčky.
Takže ovládání jde přímo z (*)
na alert('Done!')
.
Můžeme také přesunout popisek na samostatný řádek:
outer:
for (let i = 0; i < 3; i++) { ... }
continue
direktivu lze také použít se štítkem. V tomto případě spuštění kódu přeskočí na další iteraci označené smyčky.
Štítky nám neumožňují skočit na libovolné místo v kódu.
Není například možné provést toto:
break label; // jump to the label below (doesn't work)
label: for (...)
A break
direktiva musí být uvnitř bloku kódu. Technicky postačí jakýkoli označený blok kódu, např.:
label: {
// ...
break label; // works
// ...
}
…Přestože v 99,9 % případů break
se používá uvnitř smyček, jak jsme viděli ve výše uvedených příkladech.
A continue
je možné pouze zevnitř smyčky.
Shrnutí
Pokryli jsme 3 typy smyček:
while
– Podmínka se kontroluje před každou iterací.do..while
– Podmínka se kontroluje po každé iteraci.for (;;)
– Podmínka se kontroluje před každou iterací, k dispozici jsou další nastavení.
Chcete-li vytvořit „nekonečnou“ smyčku, obvykle while(true)
používá se konstrukt. Takovou smyčku, stejně jako kteroukoli jinou, lze zastavit pomocí break
směrnice.
Pokud v aktuální iteraci nechceme nic dělat a chtěli bychom přesměrovat na další, můžeme použít continue
směrnice.
break/continue
podpůrné štítky před smyčkou. Štítek je jediný způsob pro break/continue
uniknout z vnořené smyčky a přejít do vnější smyčky.