Laços while e do...while
Esta aula aborda os laços while e do...while em JavaScript, explicando suas diferenças, condições de parada e como evitar loops infinitos. Inclui exemplos práticos, boas práticas e exercícios com respostas colapsáveis.
Os laços while e do...while são estruturas de repetição fundamentais em JavaScript que executam um bloco de código enquanto uma condição especificada for verdadeira. Diferentemente do for, que é mais adequado quando sabemos o número de iterações, esses laços são ideais para situações em que a repetição depende de uma condição que pode mudar durante a execução. Nesta aula, vamos explorar suas diferenças, como definir condições de parada seguras e como evitar loops infinitos, um erro comum que pode travar seu programa.
Entender o comportamento desses laços é essencial para escrever código eficiente e evitar bugs. Vamos começar com as diferenças entre while e do...while.
Diferenças
A principal diferença entre while e do...while está no momento em que a condição é avaliada. No laço while, a condição é testada antes da execução do bloco de código. Se a condição for falsa desde o início, o bloco nunca será executado. Já no do...while, o bloco é executado pelo menos uma vez, e a condição é testada após a primeira execução. Isso garante que o código dentro do do...while sempre rode pelo menos uma vez, independentemente da condição.
Essa diferença é crucial em situações onde você precisa garantir que uma ação ocorra antes de verificar se deve continuar. Por exemplo, ao solicitar entrada do usuário até que seja válida, muitas vezes é mais natural usar do...while para exibir a mensagem ao menos uma vez.
Exemplo prático:
// while: condição testada antes
let i = 10;
while (i < 5) {
console.log('Este código não será executado');
}
// do...while: condição testada depois
let j = 10;
do {
console.log('Este código será executado uma vez');
} while (j < 5);
No primeiro exemplo, a condição i < 5 é falsa desde o início, então o bloco nunca é executado. No segundo, o bloco é executado uma vez antes de a condição ser testada.
Condições de parada
A condição de parada é a expressão booleana que determina se o laço continua ou não. Enquanto a condição for true, o laço continua; quando se torna false, o laço para. É fundamental que a condição eventualmente se torne falsa, caso contrário teremos um loop infinito. A condição pode ser qualquer expressão que resulte em um valor booleano, como comparações (>, <, ===), chamadas de função ou mesmo variáveis.
Exemplo de condição de parada com contador:
let contador = 0;
while (contador < 5) {
console.log('Iteração ' + contador);
contador++;
}
Aqui, a condição é contador < 5. A cada iteração, incrementamos o contador, garantindo que eventualmente a condição se torne falsa. Se esquecermos de atualizar o contador, o laço nunca pararia.
Outro exemplo com condição baseada em entrada do usuário (simulado):
let resposta;
do {
resposta = prompt('Digite "sair" para encerrar:');
} while (resposta !== 'sair');
Nesse caso, a condição verifica se a resposta é diferente de "sair". O laço continua até que o usuário digite "sair".
Loops infinitos (e como evitar)
Um loop infinito ocorre quando a condição do laço nunca se torna falsa, fazendo com que o bloco seja executado indefinidamente. Isso pode travar o navegador ou o ambiente de execução, consumindo toda a CPU e memória. As causas comuns são: esquecer de atualizar a variável de controle, condição sempre verdadeira, ou erro de lógica.
Exemplo de loop infinito:
let i = 0;
while (i < 10) {
console.log(i);
// esquecemos de incrementar i
}
Para evitar loops infinitos, siga estas boas práticas:
- Atualize a variável de controle: Certifique-se de que dentro do laço haja uma instrução que modifique a condição (ex: incremento, decremento, mudança de estado).
- Verifique a condição: Garanta que a condição pode se tornar falsa em algum momento. Evite condições como
trueou1 === 1sem uma saída explícita combreak. - Use um contador máximo: Em loops potencialmente perigosos, adicione um contador de segurança que interrompa o laço após um número máximo de iterações.
- Teste com valores pequenos: Antes de executar em produção, teste o laço com poucas iterações para verificar se ele termina.
Exemplo com contador de segurança:
let maxIteracoes = 1000;
let contador = 0;
while (condicao) {
// código
contador++;
if (contador > maxIteracoes) {
console.log('Loop interrompido por segurança');
break;
}
}
Outra forma de evitar loops infinitos é usar a instrução break para sair do laço quando uma condição específica for atendida, mesmo que a condição principal ainda seja verdadeira.
Boas práticas e observações finais
Ao escolher entre while e do...while, prefira while quando não houver necessidade de executar o bloco pelo menos uma vez. Use do...while quando a ação deve ocorrer ao menos uma vez antes da verificação. Sempre garanta que a condição de parada seja clara e que o laço tenha um fim definido. Evite modificar variáveis de controle dentro do laço de maneira imprevisível. Lembre-se de que loops infinitos podem causar travamentos, então teste cuidadosamente.
Referências
- MDN: while
- MDN: do...while
- W3Schools: JavaScript While Loop
- JavaScript.info: Loops: while and for
- Eloquent JavaScript: Program Structure (loops)
- freeCodeCamp: JavaScript Loops Explained
Exercícios
-
Escreva um laço
whileque exiba os números de 1 a 10 no console.✓ Resposta:let i = 1; while (i <= 10) { console.log(i); i++; } -
Usando
do...while, peça ao usuário que digite um número maior que 10. Repita até que ele digite um número válido. (Simule com uma variável fixa para teste).✓ Resposta:let numero; do { numero = parseInt(prompt('Digite um número maior que 10:')); } while (numero <= 10); console.log('Número válido:', numero); -
O que acontece no código abaixo? Corrija para evitar um loop infinito.
let x = 0; while (x < 5) { console.log(x); x--; }✓ Resposta:O código decrementa
xem vez de incrementar, entãoxfica cada vez menor, nunca atingindo 5. Para corrigir, troquex--porx++.let x = 0; while (x < 5) { console.log(x); x++; } -
Escreva um laço
whileque percorra um array de nomes e exiba cada nome no console. Use o array['Ana', 'Bruno', 'Carla'].✓ Resposta:const nomes = ['Ana', 'Bruno', 'Carla']; let i = 0; while (i < nomes.length) { console.log(nomes[i]); i++; } -
Crie um laço
do...whileque gere números aleatórios entre 1 e 6 (simulando um dado) até que o número 6 seja sorteado. Exiba cada resultado.✓ Resposta:let resultado; do { resultado = Math.floor(Math.random() * 6) + 1; console.log('Resultado:', resultado); } while (resultado !== 6); console.log('Parou!');