Laços Passo A Passo
Laços de repetição no JavaScript: o que realmente acontece quando você roda um loop
A maioria dos iniciantes aprende laços passo a passo como se fosse uma receita mágica, mas na prática você provavelmente vai passar mais tempo debugging bugs de variável que mudou no lugar errado do que realmente escrevendo loops corretos. Vou explicar como isso funciona sem enrolação. Um laço é simplesmente uma estrutura que repete um bloco de código enquanto uma condição for verdadeira ou até que um número definido de iterações seja atingido. Em JavaScript, os três tipos principais são for, while e do...while. O for é o mais usado no dia a dia para percorrer arrays e coleções. O while testa a condição antes de executar. O do...while garante que o bloco rode pelo menos uma vez porque testa a condição depois. Vamos começar com o for clássico, que é o que eu mais vejo pessoas confundindo:
for (inicialização; condição; atualização) { código } A parte da inicialização roda uma única vez antes de tudo. A condição é verificada antes de cada iteração. Se for falsa, o loop para. A atualização roda no final de cada iteração. Parece simples, mas aqui mora o problema que quase ninguém menciona: o escopo da variável de controle. Quando você usa var no lugar de let para a variável do loop, ela vira uma variável global ou de function scope, não de block scope. Isso significa que se você criar múltiplos loops ou closures dentro deles, todos vão compartilhar a mesma instância da variável. Eu levei duas horas numa sexta-feira à tarde pra descobrir que um bug meu vinha exatamente disso: estava usando var num for loop para agendar timeouts com índices, e todos os timeouts acabavam usando o último valor do índice porque a variável já tinha sido incrementada demais antes de qualquer callback rodar.
A solução foi trocar var por let, que cria uma nova vinculação por iteração do loop. Problema resolvido em trinta segundos após duas horas de frustração.

Quando usar cada tipo de laço
O for clássico é ideal quando você sabe antecipadamente quantas iterações precisa. O for...of é melhor para percorrer arrays, strings, mapas e sets porque não te expõe o índice e evita bugs de off-by-one. O for...in serve para iterar sobre as propriedades enumeráveis de um objeto, mas cuidado: a ordem das chaves não é garantida e ele também herda propriedades da cadeia de protótipos, então se você não filtrar com hasOwnProperty, vai receber coisas que não esperava. O while é a escolha certa quando a quantidade de iterações depende de uma condição externa que você não controla, como esperar por uma resposta de API ou ler dados de um stream. O do...while é raro de usar, mas útil em menus de interface onde você quer mostrar as opções pelo menos uma vez antes de perguntar se o usuário quer continuar.
Pegadinhas que ninguém conta
Loops aninhados com arrays grandes são uma fonte comum de problemas de performance. Um for dentro de outro for tem complexidade O(n²), então se seu array tem 10.000 elementos, você está rodando 100 milhões de iterações. Em vez disso, use Set para verificações de pertinência ou reestruture os dados com um map indexado. Outro erro frequente é modificar o array enquanto itera sobre ele com for clássico. Se você remove elementos durante o loop, o índice fica dessincronizado e elementos serão pulados. Use filter para criar um novo array ou iterde de trás pra frente (começando do último índice e decrementando) se precisar remover in-place. Infinit loops acontecem mais do que você imagina. Já vi gente esquecer a parte de atualização no for, usar == ao invés de !== em comparações de condição, e loops while que dependem de floating point para terminar — o que pode nunca acontecer devido a imprecisão de ponto flutuante. Sempre use um contador como safeguarda em loops while: coloque um limite máximo de iterações e lance um erro se o loop exceder esse limite.
Laços passo a passo: exemplos práticos
Aqui estão situações reais que eu encontro todo dia no trabalho: Para transformar um array de strings em maiúsculas, em vez de um for tradicional, o map é mais conciso e evita bugs de índice: const resultado = array.map(item => item.toUpperCase());
.jpg)
Para encontrar o primeiro elemento que satisfaz uma condição, some() é mais direto do que quebrar um loop com break: const encontrado = array.find(item => item.id === alvo); Para acumular valores numéricos, reduce substitui loops manuais com variáveis acumuladoras:
const soma = array.reduce((acumulador, atual) => acumulador + atual, 0); O problema é que reduce esconde a lógica de quem lê o código pela primeira vez. Às vezes um for loop simples é mais legível do que um reduce de três linhas. Não tenha orgulho de ser esperto — código legível vence código inteligente na maior parte do tempo.
Alternativas quando loops tradicionais falham
Se você precisa processar itens de forma assíncrona em sequência, um for...of com async/await funciona, mas forEach com async não espera o promise resolver antes de ir para o próximo. Use Promise.all se a ordem não importar e quiser parallelismo, ou encadeie promise.then() se precisar de execução sequencial estrita. Para iteradores customizados, implemente o protocolo Iterable definindo [Symbol.iterator]. Isso permite usar for...of em seus próprios objetos, o que é muito mais limpo do que expor um método next() manual para quem vai usar sua API. Laços passo a passo são fundamentais em qualquer linguagem de programação, e dominá-los bem evita muita dor de cabeça no dia seguinte. O segredo não é decorar sintaxe, é entender o que acontece em cada etapa e saber quando não usar loop algum.

Galeria
-
Laços de fita passo a passo simples | Lacos com fita de cetim, Fazer um ... -
Laços de fita: ideias e passo a passo - Artesanato Passo a Passo ...