O for no JavaScript, e qual loop usar em cada caso
Loops do JavaScript comparados
O for do JavaScript e todos os outros loops, comparados ao vivo | We.Inc
for, for...of, for...in, while, do...while e forEach lado a lado. Rode cada loop em um array, uma string, um objeto ou um Map e veja a saída, ou o erro que ele lança.
Um for clássico tem três partes: for (let i = 0; i < arr.length; i++) { ... }. Use-o quando precisar do índice ou de um passo personalizado. Para valores simples use for...of, para as chaves de um objeto use for...in ou Object.entries, e use while quando não souber de antemão quantas voltas serão necessárias.
Qual loop serve para cada tarefa
Loop
Melhor para
Dá para sair antes?
for (let i = 0; i < n; i++)
Contagem, acesso por índice, andar para trás ou de 2 em 2
Sim
for (const x of iterable)
Valores de arrays, strings, Maps, Sets, NodeLists
Sim
for (const key in obj)
Chaves de um objeto simples (inclui as herdadas)
Sim
while (condition)
Repetir até algo mudar, quantidade desconhecida
Sim
do { } while (condition)
O mesmo, mas sempre roda pelo menos uma vez
Sim
arr.forEach(fn)
Efeitos colaterais em cada item do array
Não (só lançando um erro)
Todos os loops desta página repetem código, mas diferem no que entregam a cada volta, no que conseguem percorrer e em como você sai deles. O executor abaixo permite apontar cada loop para quatro tipos de dados e ver a saída real, o que deixa fácil identificar erros como for...in em um array ou for...of em um objeto simples.
Escolha um loop e um tipo de dado. A página executa esse loop de verdade no seu navegador.
O painel de saída lista o que a variável do loop guardava em cada volta, ou o erro que a combinação lança.
Ative a opção de break para parar na terceira volta e ver quais loops oferecem suporte a isso.
Copie qualquer padrão dos exemplos mais abaixo.
Declare o contador com let, não com var. Com let cada volta ganha a sua própria cópia, então os callbacks criados dentro do loop enxergam o número certo.
Prefira const em for...of e for...in quando não for reatribuir a variável; cada volta ganha uma nova ligação.
O forEach não espera callbacks assíncronos. Para aguardar cada item por vez, use for...of com await dentro de uma função async.
Garanta que a condição de um while possa se tornar falsa. Altere dentro do corpo a variável que ela testa, ou a aba vai travar.
Perguntas frequentes
Qual é a diferença entre for...of e for...in?
for...of entrega valores de qualquer coisa iterável, como os itens de um array ou os caracteres de uma string. for...in entrega nomes de propriedades como strings, incluindo as enumeráveis herdadas. Em um array, for...in produz '0', '1', '2' em vez dos itens.
Como saio de um forEach?
Não dá, a não ser lançando um erro. Troque por for...of, que aceita break, ou por some, every, find ou findIndex, que param sozinhos assim que têm uma resposta.
Como percorro um objeto em JavaScript?
Use for (const [key, value] of Object.entries(obj)). Ele cobre só as chaves próprias do objeto e entrega as duas partes. Usar for...of diretamente em um objeto simples lança TypeError: obj is not iterable.
Como saio de dois loops aninhados de uma vez?
Coloque um label antes do loop externo e use-o com break: outer: for (...) { for (...) { if (found) break outer; } }. Já continue outer pula para a próxima volta do loop externo.
Como percorro de trás para frente?
Comece no último índice e conte para baixo: for (let i = arr.length - 1; i >= 0; i--). Essa também é a forma segura de remover itens com splice durante o loop, já que as posições que você ainda vai visitar não mudam de lugar.
Entendendo as três partes de um for
A primeira parte roda uma vez antes de tudo e geralmente cria o contador. A segunda é verificada antes de cada volta, e o loop termina assim que ela é falsa. A terceira roda depois de cada volta, geralmente para avançar o contador.
Qualquer parte pode ficar vazia. for (;;) é um loop que só termina com break ou return, o que às vezes é útil em lógica de nova tentativa com uma saída clara lá dentro.
break, continue e labels
break sai imediatamente do loop mais interno. continue pula o resto da volta atual e passa para a próxima. Os dois funcionam em for, for...of, for...in, while e do...while, mas não em um callback de forEach, onde return só encerra aquela chamada.
Um label é um nome seguido de dois-pontos na frente de uma instrução. break label e continue label passam então a mirar essa instrução externa, o que poupa você de controlar uma flag de encontrado entre loops aninhados.
Padrões de loop para copiar
for clássico, para frente, para trás e em passos
Mude o início, a condição ou o passo para contar do jeito que quiser.
for...of com o índice
entries() junta cada valor com a sua posição, então você tem os dois sem contador.
while e do...while
do...while verifica a condição depois do corpo, então o corpo roda uma vez mesmo quando a condição já começa falsa.
Saindo de loops aninhados com um label
break grid para os dois loops assim que a primeira correspondência é encontrada.
Aguardando cada item em ordem
for...of pausa em cada await. O mesmo código dentro de um forEach dispararia todas as requisições de uma vez, sem esperar.
Executor de loops
Escolha um loop e alguns dados. O loop roda de verdade, e cada volta aparece listada abaixo.
Loop
Dados
Array
String
Objeto simples
Map
break depois da terceira volta
O que roda
Saída
Volta {n}: {v}
O forEach não tem break. O return dentro do callback só encerra aquela chamada, então todas as voltas continuam rodando.