Il ciclo for è una delle istruzioni più usate per eseguire più volte la stessa logica.
In JavaScript è formato dalla parola chiave for, da un'intestazione racchiusa tra parentesi tonde (()) e da un blocco di codice che contiene il corpo del ciclo, racchiuso tra parentesi graffe ({}).
for (initialization; condition; step) {
// code that is executed repeatedly as long as the condition is
// true
}
L'inizializzazione di solito predispone una variabile contatore, la condizione verifica se il ciclo deve continuare o fermarsi e il passo incrementa il contatore alla fine di ogni ripetizione. Le singole parti dell'intestazione sono separate da punti e virgola.
const list = ['a', 'b', 'c'];
for (let i = 0; i < list.length; i++) {
// code that should be executed for each item in the array
}
Tutte e tre le parti dell'intestazione sono facoltative. In pratica si usano raramente. Puoi leggere di più in proposito nella documentazione MDN.
I cicli for si possono annidare, per esempio per iterare su array annidati (multidimensionali). Assicurati di usare una variabile contatore diversa per ogni ciclo.
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]
}
}
All'interno del corpo di un ciclo puoi usare la parola chiave break per interrompere del tutto l'esecuzione del ciclo.
Al contrario, la parola chiave continue interrompe solo l'esecuzione dell'iterazione corrente e passa a quella successiva.
Quando lavori con cicli annidati, per impostazione predefinita break e continue si applicano sempre al ciclo più interno.
Puoi usare le etichette per cambiare questo comportamento.
Un'etichetta è un nome identificatore seguito da due punti.
Si mette davanti (o sopra) il ciclo.
L'etichetta si può poi combinare con break o continue per definire a quale ciclo deve applicarsi l'istruzione.
outer: for (let i = 0; i < 10; i++) {
for (let j = 0; j < 10; j++) {
// ...
if (j > 5) {
continue outer;
}
// ...
}
}
Devi fare attenzione a dichiarare correttamente la variabile contatore quando hai a che fare con il codice asincrono.
Vediamo un esempio in cui sommiamo la variabile contatore in modo asincrono con setTimeout, dopo aver atteso 1 secondo.
Se dichiari il contatore con var o con let ma fuori dall'intestazione, il codice non produce il risultato atteso.
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)
In questi due casi i non è limitato allo scope di una singola iterazione del ciclo.
Nel momento in cui viene calcolata la somma, i ha già raggiunto il suo valore finale 4, il che porta a una somma pari a 4 + 4 + 4 = 12.
Questo problema si può evitare dichiarando il contatore con let all'interno dell'intestazione.
Questo ha l'effetto particolare che ogni iterazione ottiene una propria variabile let i, limitata allo scope di quella precisa esecuzione del corpo del ciclo.
Quindi, quando la somma viene calcolata più tardi, ogni funzione callback fa riferimento alla propria variabile i, che contiene ancora il valore corretto.
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