A for ciklus az egyik leggyakrabban használt utasítás arra, hogy valamilyen logikát ismételten végrehajtsunk.
JavaScriptben a for kulcsszóból, kerek zárójelbe zárt fejlécből és egy kódblokkból áll, amely a ciklus kapcsos zárójelbe zárt törzsét tartalmazza.
for (initialization; condition; step) {
// code that is executed repeatedly as long as the condition is
// true
}
Az inicializálás általában beállít egy számlálóváltozót, a feltétel ellenőrzi, hogy a ciklust folytatni vagy leállítani kell-e, a léptetés pedig minden ismétlés végén növeli a számlálót. A fejléc egyes részeit pontosvesszők választják el.
const list = ['a', 'b', 'c'];
for (let i = 0; i < list.length; i++) {
// code that should be executed for each item in the array
}
A fejléc mindhárom része opcionális. A gyakorlatban ritkán használják ki ezt. Erről bővebben az MDN dokumentációban olvashatsz.
A ciklusok egymásba ágyazhatók, például hogy egymásba ágyazott (többdimenziós) tömbökön iteráljunk. Ügyelj rá, hogy minden ciklushoz külön számlálóváltozót hozz létre.
const coords = [
[1, 2],
[4, 7],
[10, -3],
];
for (let i = 0; i < coords.length; i++) {
for (let j = 0; j < coords[i].length; j++) {
// do something with coords[i][j]
}
}
break, continue és címkékA ciklustörzsön belül a break kulcsszóval teljesen leállíthatod a ciklus végrehajtását.
Ezzel szemben a continue kulcsszó csak az aktuális iteráció végrehajtását állítja le, és a következővel folytatja.
Egymásba ágyazott ciklusoknál a break és a continue alapértelmezés szerint mindig a legbelső ciklusra vonatkozik.
Ezt a viselkedést címkékkel módosíthatod.
A címke egy azonosítónév, amelyet kettőspont követ.
A ciklus elé (vagy fölé) írjuk.
Az így kapott címkét aztán a break vagy a continue mellé írva megadhatod, hogy az utasítás melyik ciklusra vonatkozzon.
outer: for (let i = 0; i < 10; i++) {
for (let j = 0; j < 10; j++) {
// ...
if (j > 5) {
continue outer;
}
// ...
}
}
Ügyelj rá, hogy helyesen deklaráld a számlálóváltozót, amikor aszinkron kóddal dolgozol.
Nézzünk egy példát, amelyben a számlálóváltozót setTimeout segítségével, 1 másodperc várakozás után aszinkron módon összegezzük.
Ha a számlálót var-ral vagy let-tel, de a fejlécen kívül deklarálod, a kód nem a várt eredményt adja.
let sum = 0;
for (var i = 1; i < 4; i++) {
setTimeout(function () { sum += i; }, 1000);
}
// eventually sum will be 12 instead of 6 (1+2+3)
let sum = 0;
let i;
for (i = 1; i < 4; i++) {
setTimeout(function () { sum += i; }, 1000);
}
// same here, eventually sum will be 12 instead of 6 (1+2+3)
Ebben a két esetben az i scope-ja nem egy adott ciklusiterációra korlátozódik.
Mire az összeg kiszámítódik, az i már elérte a végső 4 értékét, így az összeg 4 + 4 + 4 = 12 lesz.
Ez a probléma elkerülhető, ha a számlálót let-tel a fejlécen belül deklarálod.
Ennek különleges hatása, hogy minden iteráció a saját let i változóját kapja, amelynek scope-ja pontosan a ciklustörzs azon egyetlen végrehajtására korlátozódik.
Így amikor az összeg később kiszámítódik, minden callback függvény a saját i változójára hivatkozik, amely még mindig a helyes értéket tartalmazza.
let sum = 0;
for (let i = 1; i < 4; i++) {
setTimeout(function () { sum += i; }, 1000);
}
// eventually sum will be 6 (1+2+3) as expected