O clássico laço for em JavaScript
Quando você já sabe quantas vezes quer repetir uma ação, o for é a ferramenta certa. Ele concentra as três partes de um laço contado — início, condição de parada e passo — em uma única linha de cabeçalho.
Cinco iterações, cinco linhas no console. Vamos destrinchar o cabeçalho:
let i = 0roda uma única vez, antes do loop começar. É aqui que você inicializa o contador.i < 5é avaliado antes de cada iteração. Se dertrue, o corpo executa. Se derfalse, o loop termina.i++roda depois de cada iteração, logo antes da condição ser checada de novo.
As três partes são separadas por ponto e vírgula, não por vírgula. Todas são opcionais, mas omiti-las é raro — nesses casos, o mais comum é partir para um while.
Como as peças se encaixam
Vale a pena traçar um loop na mão para fixar a ordem de execução:
Passo a passo:
let i = 1— o contador é criado e recebe 1.- Verifica
i <= 3— verdadeiro, então executa o corpo. Exibe1. - Executa
i++— agoraivale 2. - Verifica
i <= 3— verdadeiro. Exibe2. - Executa
i++— agoraivale 3. - Verifica
i <= 3— verdadeiro. Exibe3. - Executa
i++— agoraivale 4. - Verifica
i <= 3— falso. Sai do laço.
A etapa de atualização roda depois do corpo, não antes. É justamente aí que muita gente se confunde.
Percorrer array em JavaScript usando índice
A tarefa mais comum de um for em JavaScript é justamente percorrer um array. O contador funciona também como índice:
Alguns pontos que vale a pena observar:
- Arrays em JavaScript começam no índice zero. O primeiro elemento fica no índice
0e o último emlength - 1. - A condição é
i < fruits.length, e nãoi <= fruits.length. Se você usar<=, o laço vai uma posição além do array e imprimeundefined. - O
ifoi declarado comlet, então seu escopo é só o do laço. Fora dele,isimplesmente não existe.
Se você só precisa dos valores e não se importa com o índice, o for...of é mais enxuto e direto — e tem uma doc dedicada só para ele.
break: saindo do loop antes da hora
O break encerra o laço na hora. Útil quando você já achou o que procurava e não faz sentido continuar percorrendo o resto:
Quando o break é executado, o controle pula direto para depois da chave de fechamento do loop. O passo de atualização não roda, a condição não é reavaliada — o loop simplesmente acabou.
continue: pulando a iteração atual
O continue pula o restante da iteração atual e vai direto para o passo de atualização. O loop continua rodando normalmente; ele só não termina a passada atual.
Os números pares caem no continue e pulam o console.log. Só os ímpares aparecem no output. O continue é bem útil quando você quer descartar certas iterações sem precisar aninhar o resto do corpo dentro de um if.
Incrementos diferentes de +1
O passo de atualização é só uma expressão. Não precisa ser i++. Dá pra ir de dois em dois:
Count down:
Percorra um array de trás pra frente — útil quando você precisa remover itens durante a iteração:
Seja qual for a sua escolha, a regra é sempre a mesma: a condição e a atualização precisam trabalhar juntas para que, em algum momento, a condição se torne false. Se isso não acontecer, o laço roda pra sempre. for (let i = 0; i < 10; i--) é um loop infinito clássico — o i está indo na direção errada.
For aninhado em JavaScript
Dá pra colocar um for dentro de outro. O laço interno executa por completo a cada iteração do laço externo.
Nove linhas no output — três iterações externas, cada uma com três internas. Dê nomes que façam sentido para cada contador (row/col, i/j) em vez de reaproveitar a mesma variável.
Um detalhe importante: break e continue só atuam no laço mais interno. Sair de um loop interno com break não interrompe o externo. Se você precisa disso, use uma flag e cheque ela no loop de fora, ou então extraia o trabalho aninhado para uma função e use return para sair.
Armadilhas comuns
Algumas coisas que costumam pegar quem está começando:
Erros de off-by-one. i <= arr.length roda uma vez a mais do que deveria; i < arr.length - 1 para uma posição antes do fim. A forma padrão é i < arr.length.
Esquecer de atualizar o contador. Se você esquecer o i++ (ou equivalente), o contador nunca muda e o loop roda para sempre:
for (let i = 0; i < 10; ) {
console.log(i); // nunca termina
}
Usar var no contador. Como var tem escopo de função, o contador "vaza" para fora do loop e pode causar surpresas desagradáveis em closures. Fique com let.
Alterar o array enquanto itera nele. Remover itens durante a iteração bagunça os índices e você acaba pulando elementos. Se precisar remover, percorra o array de trás para frente (for decrescente) ou monte um novo array com filter.
Quando usar outra alternativa
O for clássico está sempre à disposição, mas o JavaScript oferece atalhos mais curtos para os casos mais comuns:
- Para percorrer os valores de um array:
for (const item of array)fica mais limpo. - Para transformar um array:
array.map(fn)devolve um novo array. - Para filtrar:
array.filter(fn). - Para somar ou reduzir:
array.reduce(fn, start). - Para apenas executar algo em cada elemento:
array.forEach(fn).
Recorra ao for clássico quando você realmente precisa do índice, precisa pular ou interromper o loop no meio (com break e continue), ou quer passos diferentes — tipo contar de trás para frente ou de dois em dois.
A seguir: laços while
O laço for brilha quando você já sabe o intervalo de antemão. Quando não sabe — ou seja, quando quer continuar executando até que alguma condição mude — while e do...while se encaixam melhor. É esse o tema da próxima página.
Perguntas frequentes
Qual é a sintaxe do for em JavaScript?
São três partes separadas por ponto e vírgula dentro dos parênteses: for (inicialização; condição; atualização) { ... }. A inicialização roda uma única vez, a condição é testada antes de cada iteração e a atualização acontece no final de cada uma. O formato mais comum é for (let i = 0; i < 10; i++) { ... }.
Como percorrer um array com for em JavaScript?
Dá pra usar o for clássico com índice: for (let i = 0; i < arr.length; i++) { console.log(arr[i]); }. Quando você não precisa do índice, o for...of fica bem mais limpo: for (const item of arr) { ... }. E se a ideia for transformar ou filtrar os dados, métodos como map e filter costumam ser a melhor escolha.
Como funcionam o break e o continue dentro do for?
O break sai do loop na hora — a execução pula direto pro código depois do laço. Já o continue pula o resto da iteração atual, vai pra etapa de atualização e testa a condição de novo. Os dois afetam apenas o loop mais interno, a não ser que você use labels.
Por que meu for está rodando para sempre?
Quase sempre é porque a atualização nunca leva a condição pra false. Por exemplo, for (let i = 0; i < 10; i--) roda infinitamente, já que i começa em 0 e só fica mais negativo. Revise a condição e a atualização juntas — elas precisam fazer sentido para que a condição, em algum momento, se torne falsa.