Do for clássico ao reduce moderno — guia prático com exemplos reais, boas práticas e armadilhas comuns.
Loops são estruturas de controle que permitem executar um bloco de código várias vezes, automaticamente, sem repetir o código manualmente.
for (let i = 0; i < 5; i++) {
console.log(i);
}
0
1
2
3
4
for, while, do...while, for...of e for...in. Além de métodos modernos como forEach, map, filter e reduce.| Loop | Uso principal |
|---|---|
| for | Loop clássico com contador (mais usado) |
| while | Repete enquanto condição for verdadeira |
| do...while | Executa pelo menos 1 vez, depois verifica condição |
| for...of | Percorre valores de arrays, strings e iteráveis |
| for...in | Percorre chaves (propriedades) de objetos |
O for é o loop mais clássico e usado. Ideal quando você sabe exatamente quantas vezes quer iterar.
for (inicialização; condição; incremento) {
// código executado a cada iteração
}
for (let i = 0; i < 5; i++) {
console.log(i);
}
let i = 0 → inicializa o contadori < 5 → verifica a condiçãoi++ → incrementaPercorrendo um array:
const nomes = ["Ana", "João", "Carlos"];
for (let i = 0; i < nomes.length; i++) {
console.log(nomes[i]);
}
// "Ana"
// "João"
// "Carlos"
Loop reverso (de trás pra frente):
for (let i = 4; i >= 0; i--) {
console.log(i);
}
// 4, 3, 2, 1, 0
O while repete o bloco enquanto a condição for verdadeira. Use quando não sabe exatamente quantas iterações vai precisar.
while (condição) {
// código
}
let i = 0;
while (i < 5) {
console.log(i);
i++;
}
// 0, 1, 2, 3, 4
while (true) {
console.log("nunca para");
// só use com break controlado!
}
O do...while é similar ao while, mas garante que o bloco seja executado pelo menos uma vez, mesmo que a condição seja falsa desde o início.
do {
// código executado ao menos 1x
} while (condição);
let i = 0;
do {
console.log(i);
i++;
} while (i < 5);
// 0, 1, 2, 3, 4
| Loop | Executa se condição = false? |
|---|---|
| while | ❌ Não executa nenhuma vez |
| do...while | ✅ Executa pelo menos 1 vez |
let i = 10;
while (i < 5) {
console.log("while"); // não executa
}
do {
console.log("do...while"); // executa 1 vez!
} while (i < 5);
O for...of percorre valores de arrays, strings, Maps, Sets e qualquer iterável. É mais limpo e legível que o for clássico para arrays.
for (const valor of iterável) {
// código
}
const numeros = [10, 20, 30];
for (const n of numeros) {
console.log(n);
}
// 10, 20, 30
for (const letra of "JavaScript") {
console.log(letra);
}
// J, a, v, a, S, c, r, i, p, t
const usuarios = [
{ nome: "Igor", idade: 25 },
{ nome: "Ana", idade: 20 }
];
for (const u of usuarios) {
console.log(u.nome);
}
for...of para arrays no lugar do for clássico — é mais legível e menos propenso a erros de índice.O for...in percorre as chaves (propriedades) de um objeto. É feito para objetos literais, não para arrays.
const pessoa = {
nome: "Igor",
idade: 25,
cidade: "SP"
};
for (const chave in pessoa) {
console.log(chave, pessoa[chave]);
}
// nome Igor
// idade 25
// cidade SP
for...in em arrays! Ele percorre índices como strings e pode incluir propriedades herdadas do protótipo. Use for...of ou forEach para arrays.// ❌ evite
for (const i in [10, 20, 30]) {
// i é "0", "1", "2" — strings!
}
// ✅ use for...of
for (const n of [10, 20, 30]) {
console.log(n); // 10, 20, 30
}
Dois comandos para controlar o fluxo dentro de loops:
break
Para o loop completamente e sai dele.
continue
Pula a iteração atual e vai para a próxima.
for (let i = 0; i < 10; i++) {
if (i === 5) break;
console.log(i);
}
// 0, 1, 2, 3, 4
for (let i = 0; i < 5; i++) {
if (i === 2) continue;
console.log(i);
}
// 0, 1, 3, 4 (pulou o 2)
Métodos de array modernos que muitas vezes substituem loops por um código mais expressivo e funcional.
const nums = [1, 2, 3];
nums.forEach(n => {
console.log(n);
});
// 1, 2, 3
const nums = [1, 2, 3];
const dobrados = nums.map(n => n * 2);
console.log(dobrados); // [2, 4, 6]
const nums = [1, 2, 3, 4];
const pares = nums.filter(n => n % 2 === 0);
console.log(pares); // [2, 4]
| Método | O que faz | Retorna |
|---|---|---|
| forEach | Executa função para cada item | undefined |
| map | Transforma cada item | Novo array |
| filter | Filtra itens por condição | Novo array |
map quando quiser transformar dados. Use filter quando quiser filtrar dados. Evite usar forEach quando map/filter resolveriam melhor.O reduce acumula valores de um array em um único resultado. É o método mais poderoso, mas também o mais complexo.
array.reduce((acumulador, valorAtual) => {
return novoAcumulador;
}, valorInicial);
const nums = [1, 2, 3, 4];
const soma = nums.reduce((acc, n) => acc + n, 0);
console.log(soma); // 10
const frutas = ["maçã", "banana", "maçã", "maçã"];
const contagem = frutas.reduce((acc, fruta) => {
acc[fruta] = (acc[fruta] || 0) + 1;
return acc;
}, {});
console.log(contagem);
// { maçã: 3, banana: 1 }
reduce é poderoso porque pode fazer tudo que map e filter fazem — mas use-os separados quando possível, pois são mais legíveis.Loops aninhados (nested loops) são loops dentro de loops. Úteis para matrizes e tabelas.
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 2; j++) {
console.log(i, j);
}
}
// 0 0 | 0 1
// 1 0 | 1 1
// 2 0 | 2 1
Labels são rótulos que permitem sair de loops externos com break ou continue:
outer: for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
if (i === 1 && j === 1) break outer;
console.log(i, j);
}
}
// 0 0 | 0 1 | 0 2 | 1 0 (para aqui)
for...of > for
Prefira for...of para arrays — mais limpo e sem erros de índice.
map/filter > forEach
Use métodos funcionais quando precisar transformar ou filtrar dados.
const no loop
Use const dentro de for...of e for...in (não varia).
let no for clássico
Use let para o contador do for (i) — ele precisa variar.
// ✅ for...of para arrays
for (const item of array) { ... }
// ✅ map para transformar
const dobro = nums.map(n => n * 2);
// ✅ filter para filtrar
const ativos = usuarios.filter(u => u.ativo);
// ✅ sempre inicialize a variável
let i = 0;
while (i < 5) { i++; }
// ❌ esquecer incremento → loop infinito
while (i < 5) {
console.log(i); // nunca incrementa!
}
// ❌ for...in em array
for (const i in [1, 2, 3]) {} // índices como string
// ❌ modificar array enquanto percorre
for (let i = 0; i < arr.length; i++) {
arr.pop(); // comportamento imprevisível!
}
Calculando a soma dos números ímpares de um array usando diferentes abordagens:
const numeros = [1, 2, 3, 4, 5];
let soma = 0;
for (const n of numeros) {
if (n % 2 === 0) continue;
soma += n;
}
console.log("Soma dos ímpares:", soma); // 9
const numeros = [1, 2, 3, 4, 5];
const soma = numeros
.filter(n => n % 2 !== 0)
.reduce((acc, n) => acc + n, 0);
console.log("Soma dos ímpares:", soma); // 9
// for → loop clássico com contador
// while → baseado em condição
// do-while → executa pelo menos 1 vez
// for...of → valores de arrays/strings
// for...in → chaves de objetos
// forEach → executar para cada item
// map → transformar array
// filter → filtrar array
// reduce → acumular em um valor
for → aprenda while → use for...of no dia a dia → domine map / filter / reduce → explore loops aninhados.