Il ciclo for in JavaScript e tutti gli altri, a confronto dal vivo | We.Inc
for, for...of, for...in, while, do...while e forEach fianco a fianco. Esegui ogni ciclo su un array, una stringa, un oggetto o una Map e guarda l'output, o l'errore che lancia.
Un classico ciclo for ha tre parti: for (let i = 0; i < arr.length; i++) { ... }. Usalo quando ti serve l'indice o un passo personalizzato. Per i semplici valori usa for...of, per le chiavi di un oggetto usa for...in o Object.entries, e usa while quando non sai in anticipo quanti giri ti servono.
Quale ciclo è adatto al compito
Ciclo
Ideale per
Si può interrompere prima?
for (let i = 0; i < n; i++)
Contare, accedere per indice, andare all'indietro o a passi di 2
Sì
for (const x of iterable)
Valori di array, stringhe, Map, Set, NodeList
Sì
for (const key in obj)
Chiavi di un oggetto semplice (incluse quelle ereditate)
Sì
while (condition)
Ripetere finché qualcosa cambia, numero di giri sconosciuto
Sì
do { } while (condition)
Come sopra, ma viene sempre eseguito almeno una volta
Sì
arr.forEach(fn)
Effetti collaterali su ogni elemento dell'array
No (solo lanciando un errore)
Ogni ciclo di questa pagina ripete del codice, ma differiscono in cosa ti passano a ogni giro, su cosa possono ciclare e come se ne esce. Il runner qui sotto ti permette di applicare ogni ciclo a quattro tipi di dati e di guardare l'output reale, il che rende facili da individuare errori come for...in su un array o for...of su un oggetto semplice.
Scegli un ciclo e un tipo di dato. La pagina esegue davvero quel ciclo nel tuo browser.
Il pannello di output elenca cosa conteneva la variabile del ciclo a ogni giro, oppure l'errore che quella combinazione lancia.
Attiva l'opzione break per fermarti al terzo giro e vedere quali cicli la supportano.
Copia qualsiasi pattern dagli esempi più in basso.
Dichiara il contatore con let, non con var. Con let ogni giro ha la propria copia, quindi le callback create dentro il ciclo vedono il numero giusto.
Preferisci const in for...of e for...in quando non riassegni la variabile; ogni giro riceve un nuovo binding.
forEach non aspetta le callback async. Per fare await su ogni elemento in sequenza, usa for...of con await dentro una funzione async.
Assicurati che la condizione di un ciclo while possa diventare falsa. Modifica la variabile che controlla dentro il corpo, altrimenti la scheda si blocca.
Domande frequenti
Qual è la differenza tra for...of e for...in?
for...of ti dà i valori di qualsiasi cosa iterabile, come gli elementi di un array o i caratteri di una stringa. for...in ti dà i nomi delle proprietà come stringhe, comprese quelle enumerabili ereditate. Su un array, for...in produce '0', '1', '2' invece degli elementi.
Come esco da un ciclo forEach?
Non puoi, se non lanciando un errore. Passa a for...of, che supporta break, oppure a some, every, find o findIndex, che si fermano da soli appena hanno una risposta.
Come ciclo su un oggetto in JavaScript?
Usa for (const [key, value] of Object.entries(obj)). Copre solo le chiavi proprie dell'oggetto e ti dà entrambe le parti. Usare for...of direttamente su un oggetto semplice lancia TypeError: obj is not iterable.
Come esco da due cicli annidati in una volta?
Metti un'etichetta prima del ciclo esterno e usala con break: outer: for (...) { for (...) { if (found) break outer; } }. continue outer invece salta al giro successivo del ciclo esterno.
Come ciclo all'indietro?
Parti dall'ultimo indice e conta alla rovescia: for (let i = arr.length - 1; i >= 0; i--). È anche il modo sicuro per rimuovere elementi con splice durante il ciclo, perché le posizioni che devi ancora visitare non si spostano.
Leggere le tre parti di un ciclo for
La prima parte viene eseguita una volta prima di tutto il resto e di solito crea il contatore. La seconda viene controllata prima di ogni giro, e il ciclo termina appena è falsa. La terza viene eseguita dopo ogni giro, di solito per far avanzare il contatore.
Qualsiasi parte può essere lasciata vuota. for (;;) è un ciclo che termina solo con break o return, cosa a volte utile per la logica di retry con una chiara uscita interna.
break, continue ed etichette
break esce immediatamente dal ciclo più interno. continue salta il resto del giro corrente e passa al successivo. Entrambi funzionano in for, for...of, for...in, while e do...while, ma non in una callback di forEach, dove return termina solo quella singola chiamata.
Un'etichetta è un nome seguito da due punti davanti a un'istruzione. break label e continue label puntano poi a quell'istruzione esterna, il che ti evita di gestire un flag found tra cicli annidati.
Pattern di cicli da copiare
For classico, in avanti, all'indietro e a passi
Cambia l'inizio, la condizione o il passo per contare come preferisci.
for...of con l'indice
entries() abbina ogni valore alla sua posizione, così ottieni entrambi senza un contatore.
while e do...while
do...while controlla la condizione dopo il corpo, quindi il corpo viene eseguito una volta anche quando la condizione parte falsa.
Uscire da cicli annidati con un'etichetta
break grid ferma entrambi i cicli appena viene trovata la prima corrispondenza.
Await su ogni elemento in ordine
for...of si ferma a ogni await. Lo stesso codice dentro forEach avvierebbe tutte le richieste insieme senza aspettare.
Runner dei cicli
Scegli un ciclo e dei dati. Il ciclo viene eseguito davvero, e ogni giro è elencato qui sotto.
Ciclo
Dati
Array
Stringa
Oggetto semplice
Map
break dopo il terzo giro
Cosa viene eseguito
Output
Giro {n}: {v}
forEach non ha break. Il return dentro la callback termina solo quella singola chiamata, quindi tutti i giri vengono comunque eseguiti.