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.
Os laços while e do...while são estruturas de repetição fundamentais em JavaScript que permitem executar um bloco de código enquanto uma condição especificada for verdadeira. Diferentemente do laço for, que é mais adequado quando sabemos o número exato de iterações, os laços while e do...while são ideais para situações em que a repetição depende de uma condição que pode mudar durante a execução, como ler dados de uma entrada até que um valor específico seja fornecido.
Embora ambos sejam baseados em condições booleanas, eles diferem no momento em que a condição é avaliada: while verifica a condição antes de executar o bloco, enquanto do...while garante que o bloco seja executado pelo menos uma vez, pois a condição é verificada após a primeira iteração. Compreender essas diferenças é crucial para escrever loops corretos e evitar erros comuns, como loops infinitos.
Diferenças
A principal diferença entre while e do...while está no momento da avaliação da condição de continuação. No laço while, a condição é testada antes de cada iteração. Se a condição for falsa desde o início, o bloco de código nunca será executado. Já no laço do...while, a condição é testada após a execução do bloco, garantindo que o bloco seja executado pelo menos uma vez, independentemente da condição.
Essa diferença é especialmente útil quando você precisa executar uma ação antes de verificar se deve continuar. Por exemplo, ao solicitar entrada do usuário, você pode usar do...while para exibir o prompt pelo menos uma vez e depois repetir enquanto a entrada não for válida. Veja a sintaxe de cada um:
// while: condição testada antes de cada iteração
while (condicao) {
// bloco de código
}
// do...while: condição testada após cada iteração
do {
// bloco de código
} while (condicao);No exemplo abaixo, o laço while não executa nenhuma vez se contador for 10, enquanto o do...while executa uma vez e depois para:
let contador = 10;
while (contador < 10) {
console.log("while: " + contador); // nunca executado
contador++;
}
do {
console.log("do...while: " + contador); // executado uma vez (10)
contador++;
} while (contador < 10);Condições de parada
A condição de parada é a expressão booleana que determina se o laço continua ou termina. Em ambos os laços, a condição é avaliada a cada iteração. Se a condição retornar true, o bloco é executado novamente; se retornar false, o laço termina e a execução continua na próxima instrução após o laço.
É essencial que a condição de parada seja eventualmente falsa, caso contrário o laço se tornará infinito. A condição geralmente depende de variáveis que são modificadas dentro do bloco. Por exemplo, um contador que é incrementado até atingir um limite, ou uma flag que muda de valor quando uma condição é satisfeita. Veja um exemplo com while que imprime números de 0 a 4:
let i = 0;
while (i < 5) {
console.log(i);
i++;
}
// Saída: 0, 1, 2, 3, 4No do...while, a condição é verificada após a execução, então o bloco sempre executa pelo menos uma vez. Isso é útil quando você precisa executar uma ação antes de verificar se deve continuar. Por exemplo, ler um número do usuário até que ele digite um valor positivo:
let numero;
do {
numero = parseInt(prompt("Digite um número positivo:"));
} while (numero <= 0);
console.log("Número válido: " + numero);Note que a condição de parada deve ser cuidadosamente projetada para evitar loops infinitos. Sempre verifique se a variável da condição está sendo atualizada de forma que eventualmente torne a condição falsa.
Loops infinitos (e como evitar)
Um loop infinito ocorre quando a condição de parada nunca se torna falsa, fazendo com que o laço execute indefinidamente. Isso pode travar o navegador ou o ambiente de execução. Loops infinitos geralmente são causados por erros lógicos, como esquecer de atualizar a variável de controle, usar uma condição que sempre é verdadeira, ou modificar a variável de forma incorreta.
Exemplo clássico de loop infinito com while:
let i = 0;
while (i < 5) {
console.log(i);
// esqueci de incrementar i
}
// i nunca muda, então a condição i < 5 é sempre verdadeiraPara evitar loops infinitos, siga estas boas práticas:
- Atualize a variável de controle: Certifique-se de que a variável usada na condição é modificada dentro do bloco, de modo que a condição possa se tornar falsa.
- Use condições simples e verificáveis: Evite condições complexas que possam ser sempre verdadeiras devido a um erro lógico.
- Adicione um limite de segurança: Em loops que dependem de entrada externa, considere adicionar um contador máximo de iterações para interromper o loop se ele exceder um número razoável.
- Teste o loop com valores de fronteira: Verifique se o loop se comporta corretamente quando a condição é inicialmente falsa (no caso do
while) ou quando a condição se torna falsa após a primeira iteração.
Aqui está um exemplo de loop while com um contador de segurança:
let tentativas = 0;
const maxTentativas = 10;
let senhaCorreta = false;
while (!senhaCorreta && tentativas < maxTentativas) {
let entrada = prompt("Digite a senha:");
if (entrada === "1234") {
senhaCorreta = true;
console.log("Senha correta!");
} else {
tentativas++;
console.log("Senha incorreta. Tentativa " + tentativas);
}
}
if (!senhaCorreta) {
console.log("Número máximo de tentativas excedido.");
}No do...while, o mesmo cuidado se aplica: a condição deve eventualmente se tornar falsa. Como o bloco executa pelo menos uma vez, é ainda mais importante garantir que a primeira execução não cause um estado que impeça a condição de se tornar falsa.
Boas práticas e observações finais
Ao usar laços while e do...while, prefira while quando não houver necessidade de executar o bloco pelo menos uma vez. Use do...while quando a primeira execução for necessária, como em validações de entrada. Sempre inicialize as variáveis de controle antes do laço e atualize-as dentro do bloco. Evite modificar a variável de controle dentro da condição, pois isso pode tornar o código confuso. Por fim, lembre-se de que loops infinitos podem ser interrompidos com break (embora o uso excessivo de break possa indicar que um laço while não é a melhor escolha).
Referências
- MDN: while
- MDN: do...while
- MDN: Loops e iteração
- W3Schools: JavaScript While Loop
- JavaScript.info: Loops while e for
- Eloquent JavaScript: Program Structure (loops)
Exercícios
Escreva um laço
whileque imprima os números de 1 a 10 no console.✓ Resposta:let i = 1; while (i <= 10) { console.log(i); i++; }Escreva um laço
do...whileque solicite ao usuário um número maior que 10, repetindo até que ele digite um número válido. UseprompteparseInt.✓ 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 se a condição de um laço
whilefor falsa desde o início? E nodo...while?✓ Resposta:No
while, o bloco nunca é executado. Nodo...while, o bloco é executado uma vez e depois a condição é testada; como é falsa, o laço termina.Escreva um laço
whileque percorra um array de números e imprima apenas os números pares. Use o array:[3, 8, 12, 5, 20, 7].✓ Resposta:let numeros = [3, 8, 12, 5, 20, 7]; let i = 0; while (i < numeros.length) { if (numeros[i] % 2 === 0) { console.log(numeros[i]); } i++; } // Saída: 8, 12, 20Corrija o loop infinito abaixo:
let x = 0; while (x < 5) { console.log(x); }✓ Resposta:Falta incrementar
xdentro do loop. A versão correta é:let x = 0; while (x < 5) { console.log(x); x++; }