Olá! Boas-vindas ao curso da formação de Prática de Programação com JavaScript. Meu nome é Ju Amoasei.
Audiodescrição: Ju se descreve como uma mulher branca, de cabelo curto pintado de azul e olhos castanhos. Usa óculos de armação vermelha, piercing no nariz, brinco de argola e camiseta cinza. Ao fundo, estúdios da Alura com iluminação azulada e estante com decorações.
O foco deste curso é realmente praticar com código, testar nossos conhecimentos de forma ativa e resolver alguns dos problemas de lógica de programação que encontramos durante nossa rotina de estudos.
Nessa formação, teremos revisão de conteúdo, material suplementar e muitos desafios e exercícios para realmente colocarmos em prática tudo o que aprendemos.
É importante destacar que, como este é um curso de revisão, é necessário já ter concluído a formação anterior, que é a formação de fundamentos de JavaScript para back-end, onde apresentamos os conceitos que apenas revisaremos durante esta formação.
Nessa formação de prática, o conteúdo será revisado de forma incremental. Portanto, é recomendável seguir os cursos na ordem apresentada, para garantir que não percamos nada que seja referenciado em revisões anteriores.
É importante notar que este curso não é voltado para front-end. No entanto, toda prática realizada com JavaScript pode ser aproveitada no front-end, desde que o Node.js esteja instalado.
É essencial pausar, testar os vídeos, experimentar os exemplos, modificar e fazer os exercícios. Isso é muito importante e será enfatizado durante toda a revisão. Além disso, podemos compartilhar o que aprendemos no fórum e pedir ajuda, se necessário.
Vamos começar?
Vamos revisar laços de repetição, ou loops, como chamamos em JavaScript e em outras linguagens também.
O JavaScript, basicamente, possui três laços de repetição nativos:
for
while
do... while
Existem outros tipos de instrução que podemos utilizar no JavaScript que também têm esse comportamento repetitivo, como, por exemplo:
for... of
for... in
Neste curso, vamos focar em for
, while
e do... while
, pois os outros são mais específicos. Vamos abordar for... of
e for... in
ao abordar arrays e objetos em outros cursos.
for
Para começar, vamos nos concentrar no laço for
, que é o tipo de laço de repetição mais utilizado. Ele possui uma forma semelhante em diversas linguagens, pelo menos nas mais usadas, e é o mais comum quando estamos praticando lógica de programação e resolução de algoritmos, devido à sua versatilidade. Vamos relembrar a sintaxe dele:
for (inicialização; condição; atualização) {
}
Começamos declarando o for
, ou seja, nosso laço. Em seguida, entre parênteses, colocamos três instruções. A primeira instrução, de inicialização, é executada uma única vez, antes de tudo começar, antes mesmo do for
verificar se vai realizar a primeira iteração ou não.
A segunda instrução é a condição, também chamada de condição de parada ou de continuidade, que é avaliada antes de cada iteração. Assim, se o código chegar na linha do for
, essa condição for avaliada e resultar em false
(falso), nem a primeira iteração será realizada. Porém, se a primeira iteração ocorrer, voltamos e avaliamos a condição novamente antes de fazer a segunda.
Por último, a atualização é executada antes de começar um laço e depois de terminar o laço anterior. Assim, entramos no laço, executamos o código dentro do bloco e, antes de verificar se entramos novamente no loop para uma nova iteração, executamos o que estiver nessa instrução.
As instruções devem estar separadas por ponto e vírgula - e nenhuma delas é obrigatória. Durante os estudos, podemos encontrar casos que podem não precisar de uma ou outra instrução.
Dando um exemplo usando JavaScript, criamos uma const
chamada numero
para fazer uma tabuada de 5. Queremos um código que multiplique 5 de 1 a 10, ou seja, 5 vezes 1, 5 vezes 2, 5 vezes 3 e assim por diante.
As três instruções — inicialização, condição e atualização — referem-se a isso. Na inicialização, criamos uma let
chamada i
- que é um nome padrão, mas podemos usar qualquer nome. Iniciamos essa let i
com o número 1. Nesse caso, ela será responsável por contar as iterações. Começamos no 1 porque queremos que vá de 1 até 10.
A segunda instrução é a condição para entrar ou não no laço. Queremos que isso aconteça enquanto o valor da variável i
for menor ou igual a 10, pois queremos que pare no 10. Assim, paramos quando calculamos 5 vezes 10 igual a 50.
Desse modo, a primeira iteração vai acontecer, pois acabamos de criar a let i
com o valor de 1. Como 1 é menor que 10, a condição retorna true
(verdadeiro). A lógica funciona assim como no if
e em outras condicionais: entra no bloco enquanto a avaliação da expressão for verdadeira. No momento em que resultar em falso, saímos do laço.
A terceira instrução é a atualização, onde incrementamos o valor da variável i
.
const numero = 5;
for (let i = 1; i <= 10; i++) {
const resultado = numero * i;
console.log(`${numero} x ${i} = ${resultado}`);
}
Na prática, entramos no primeiro laço, criamos uma const
chamada resultado
para guardar o resultado da tabuada. Na primeira vez que entramos, nosso número base é sempre 5, que será multiplicado por i
.
Na primeira iteração do laço, i
é 1. Então, 5 vezes 1 é igual a 5, que é guardado na const resultado
e exibido no console.
Finalizado o bloco, antes de verificar se haverá mais um laço, atualizamos o valor de i
. Isso significa que, quando a condição for avaliada novamente, i
não vale mais 1, mas sim 2, pois a atualização já foi feita.
Lembrando que
i++
equivale ai = i + 1
, enquantoi--
equivale ai = i - 1
. Sempre que queremos incrementar um valor numérico de 1 em 1, podemos usar essa sintaxe reduzida, que é bastante comum em laços.
Seguimos esse fluxo até chegar no 10. Quando o valor de i
for 10, realizamos a operação 5 vezes 10, e o valor de let i
será atualizado para 11. A condição 11 menor ou igual a 10 resultará em falso, e não entraremos mais no laço.
Note que estamos criando uma const
dentro do for
. As variáveis criadas dentro do for
são recriadas a cada laço, então a const resultado
guardará o número enquanto o laço estiver executando. Na próxima iteração, ela será recriada com um novo número, existindo apenas dentro do laço.
Quando trabalhamos com for
, é comum enfrentarmos um problema chamado loop infinito. Isso ocorre quando um laço continua a executar sem parar, geralmente devido a um erro no código que impede a condição de saída.
Vamos apresentar dois exemplos na tabuada de 5 para ilustrar como um loop infinito pode ocorrer.
Primeiramente, se esquecermos de incluir a condição de atualização ou incremento da variável i
, o valor de i
nunca será alterado. Assim, i
nunca atingirá 11. Logo, a condição de continuidade no laço sempre será verdadeira, pois i
sempre será menor ou igual a 10. Como i
permanece 1, o laço executará indefinidamente, caracterizando um loop infinito.
const numero = 5;
for (let i = 1; i <= 10; ) {
const resultado = numero * i;
console.log(`${numero} x ${i} = ${resultado}\n`);
}
Ressaltamos que o fato de não existir uma instrução de atualização não é considerado um erro pelo JavaScript. Afinal, às vezes não precisamos de uma das três instruções.
Outro exemplo ocorre quando, ao trabalhar com operadores, invertemos o sinal da condição sem querer. Em vez de i
ser menor ou igual a 10, escrevemos que a condição de continuidade será enquanto i
for maior ou igual a 0.
Se i
for inicializado com um valor maior que 0, como 1, e for incrementado, i
sempre será maior ou igual a 0. Assim, o laço continuará executando sem parar.
const numero = 5;
for (let i = 1; i >= 0; i++) {
const resultado = numero * i;
console.log(`${numero} x ${i} = ${resultado}\n`);
}
Normalmente, o programa empilha as instruções que lhe são passadas e as executa na ordem de pilha. Um exemplo de instrução é a linha const resultado = numero * i
. Quando temos um loop infinito, as instruções se empilham indefinidamente até que o programa não consiga mais lidar com essa pilha.
Simplificadamente, quando a memória não consegue mais guardar essa pilha, isso resulta no que chamamos de estouro de pilha ou stack overflow. Isso pode travar o computador, pois está relacionado à memória disponível para o programa executar.
Atualmente, tanto o Node.js quanto os navegadores modernos possuem ferramentas para lidar com esse problema, interrompendo o laço quando detectam um possível estouro de pilha.
Se isso ocorrer, não se preocupe, é comum enfrentar loops infinitos acidentalmente. Revise o código e, se o console.log()
estiver rodando indefinidamente, pressione "Ctrl + C" para interromper o processo.
Após iniciar o laço, o programa só continua executando o restante do código quando finalizar as iterações do laço.
Isso causa o loop infinito, pois o programa continua executando as iterações sem uma instrução de saída.
break
e continue
Uma forma de gerenciar essas saídas do laço é utilizando o break
, a mesma instrução que utilizamos no switch
para sair do bloco de condicionais.
Para exemplificar, vamos trazer um código que gera 50 números aleatórios de 1 a 50 através do Math.random()
.
O
break
interrompe o laço quando encontrado, independentemente da condição de continuidade ainda ser verdadeira.
Por exemplo, esse laço vai até 50, mas se encontrar o break
antes, ele interrompe o laço na iteração em que o break
aparece e continua com o restante do código.
for (let contador = 1; contador <= 50; contador++) {
const numero = Math.floor(Math.random() * (50 - 1 + 1) + 1);
if (numero === 15) {
console.log(`${numero} em ${contador} tentativas`);
break;
}
}
Outra forma de manejar laços é usando o continue
.
O
continue
pula para a próxima iteração e desconsidera o restante do bloco atual.
Por exemplo, suponha que dentro do for
, há um bloco de código com várias instruções. Ao encontrar o continue
, a iteração é interrompida imediatamente, ignorando o restante das instruções, e passa para a próxima iteração.
let contador = 0;
for (let i = 1; i <= 20; i++) {
const numero = Math.floor(Math.random() * (50 - 1 + 1) + 1);
if (numero % 5 === 0) {
continue;
}
contador++;
}
console.log('contador', contador);
Assim, o continue
não interrompe o laço, apenas a iteração atual. Com isso, conseguimos gerenciar o laço e não executar exatamente o mesmo código em todas as iterações.
Vamos praticar e colocar esses conceitos em ação, executando os códigos para observar o funcionamento do break
e do continue
.
Voltando ao Visual Studio Code, vamos praticar com os exemplos de break
e continue
abordados na revisão.
for
com break
O primeiro código deve gerar números aleatórios de 1 a 50 e interromper o laço caso o número gerado seja 15. O laço também será interrompido após 30 tentativas, mas você pode ajustar essa quantidade caso queira. Além disso, é preciso contar a quantidade de tentativas realizadas.
Primeiramente, vamos criar o laço for
. Precisamos que esse laço rode 50 vezes, portanto, precisamos contar de 1 até 50. Por isso, na instrução de inicialização, criaremos uma let i
igual a 1.
Na condição de parada, vamos configurá-lo para parar após 30 tentativas. Isto é, o código executa enquanto i
for menor ou igual a 30. Por fim, na instrução de atualização, vamos incrementar i++
a cada iteração para conseguir alcançar a condição de parada.
for (let i = 1; i <= 30; i++) {
}
Para gerar um número aleatório no JavaScript, utilizaremos a biblioteca nativa chamada Math
. Ela possui alguns métodos para realizar operações matemáticas.
Você pode conferir a documentação do
Math.random()
do MDN para conhecer mais sobre esse método que gera números aleatórios.
Já deixamos o código pronto para criar uma constante numero
que armazenará o número aleatório gerado em cada iteração:
for (let i = 1; i <= 30; i++) {
const numero = Math.floor(Math.random() * (50 - 1 + 1) + 1);
}
O método Math.random()
gera um número aleatório entre 0 e 1, e ao multiplicá-lo por 50 e somar 1, obtemos um número entre 1 e 50. Englobamos esse código com o método Math.floor()
da mesma biblioteca. Esse método arredonda o número para baixo, retirando as casas decimais e garantindo que seja um inteiro.
Agora que já geramos números aleatórios de 1 a 50, precisamos interromper o laço caso o número gerado seja 15. Para isso, utilizamos um condicional if
. Se numero
for estritamente igual (===
) a 15, o break
é acionado, interrompendo o laço.
Antes disso, registramos a quantidade de tentativas com console.log()
. Nele, vamos concatenar textos e variáveis com a seguinte template string: ${numero} em ${i} tentativas
.
for (let i = 1; i <= 30; i++) {
const numero = Math.floor(Math.random() * (50 - 1 + 1) + 1);
if (numero === 15) {
console.log(`${numero} em ${i} tentativas`);
break;
}
}
Assim, depois que imprimimos a mensagem no console com a quantidade de tentativas, interrompemos o laço, caso o número aleatório gerado seja 15, e continuamos a executar o restante do código - independentemente de qual iteração estávamos.
Para tornar o código mais claro, substituímos o nome da variável i
por contador
. Afinal, a variável inicial não apenas controla o laço, mas também conta as iterações.
for (let contador = 1; contador <= 30; contador++) {
const numero = Math.floor(Math.random() * (50 - 1 + 1) + 1);
if (numero === 15) {
console.log(`${numero} em ${contador} tentativas`);
break;
}
}
Finalmente, podemos executar o código. No terminal integrado, dentro da pasta correta, executamos o comando node
e o nome do arquivo:
node exercicios.js
Se não retornar nada, pode ser que em 30 tentativas o número 15 não tenha sido gerado aleatoriamente. Portanto, nenhuma mensagem foi impressa no console.
Vamos fazer uma nova tentativa? Se o número 15 for gerado, o console indicará em quantas tentativas isso ocorreu:
15 em 11 tentativas
O primeiro exercício foi concluído com sucesso! O break
funciona e, inclusive, mostra a iteração em que o laço parou.
continue
Vamos continuar com o próximo exercício da revisão, que utiliza o continue
. Novamente, geraremos números aleatórios de 1 a 50, mas agora o contador será incrementado somente caso os números não sejam divisíveis por 5.
Em outras palavras, precisamos de uma maneira de contar as iterações, mas pular números como, por exemplo, 5, 10, 15, 20 ou 25. Se gerar um desses números, o contador não pode ser incrementado. Portanto, o contador e a variável de inicialização precisarão ser diferentes.
Primeiro, vamos criar um laço for
. Para controlar quantas vezes o laço é executado, vamos criar uma let i
que começa com o valor 1.
Queremos que o laço executando por 30 iterações, portanto, vamos definir a condição como 1 menor ou igual a 30. Além disso, manteremos a instrução de incremento do i
como i++
.
Para gerar um número aleatório, vamos reutilizar a linha que cria a constante numero
, a qual armazena um número inteiro de 1 a 50.
for (let i = 1; i <= 30; i++) {
const numero = Math.floor(Math.random() * (50 - 1 + 1) + 1);
}
Agora, precisamos criar uma condicional, pois queremos verificar se o número aleatório gerado não é divisível por 5 para poder incrementar o contador.
Antes disso, precisamos primeiro criar uma variável contador
, fora do for
, para contar as iterações em que o número não é divisível por 5. Essa variável não pode ficar dentro do laço, já que nem sempre deve ser atualizada.
Em seguida, no laço, basta fazer um if
com a condição numero % 5
é estritamente igual (===
) a zero. Ou seja, verificamos se o número gerado é divisível por 5.
Dica: o operador de módulo (
%
) retorna o resto da divisão do primeiro pelo segundo número.
Caso isso seja verdadeiro, vamos utilizar o continue
para interromper a iteração atual e volta ao início do for
para começar uma nova iteração. Assim, o continue
interrompe antes de executar o código que estiver depois dele nesse bloco for
. Por isso, depois do if
, precisamos incrementar contador++
.
let contador = 0;
for (let i = 1; i <= 30; i++) {
const numero = Math.floor(Math.random() * (50 - 1 + 1) + 1);
if (numero % 5 === 0) {
continue;
}
contador++;
}
Com isso, se o número aleatório gerado for divisível por 5, entramos na condicional e acionamos o continue
. Nesse momento, saímos da iteração atual e passamos para a próxima, ignorando o incremento do contador
.
Ou seja, agora temos uma variável para gerenciar os laços e garantir que sejam executados 30 vezes. E temos outra variável apenas para contar a quantidade de iterações, caso o número não seja divisível por 5.
Por fim, devemos verificar o valor da variável contador
. Para isso, fazemos um console.log()
de contador
, depois do for
. Assim, só quando o laço acabar é que vamos imprimir esse valor do contador
no console.
console.log(contador);
No terminal, executamos o comando node exercicios.js
. Verificamos que, em 30 tentativas, seis números eram divisíveis por 5 e foram ignorados.
24
No JavaScript, existe uma sintaxe que permite criar mais de uma variável por linha. Então, seria possível criar uma let i = 1
na inicialização do for
, acrescentar uma vírgula, ainda na primeira instrução, e inicializar contador
com zero.
Exemplo:
// let contador = 0;
for (let i = 1, contador = 0; i <= 30; i++) {
const numero = Math.floor(Math.random() * (50 - 1 + 1) + 1);
if (numero % 5 === 0) {
continue;
}
contador++;
}
console.log(contador);
O JavaScript aceita isso, mesmo fora do for
, é uma sintaxe que você pode usar no seu dia a dia. Pessoalmente, a Ju não gosta muito de usar essa sintaxe. Ela prefere colocar uma declaração embaixo da outra, porque fica mais explícito.
Mas, é possível usá-la caso você queira criar mais de uma variável para ser gerenciada dentro desse loop. No entanto, ela talvez não funcione tão bem no nosso exemplo. Vamos testar?
Quando executamos node exercicios.js
, acontece um erro. Vamos analisar esse erro:
ReferenceError: contador is not defined.
Nesse exemplo, a variável contador
foi criada dentro do laço for
. Quando saímos desse bloco, as variáveis que foram criadas dentro dele não existem do lado de fora.
Se quiséssemos apenas passar console.log()
de contador
dentro do for
, conseguiríamos executar o código. Assim, imprimiríamos no console todas as iterações que geraram um número não divisível por 5.
Contudo, como queremos que a variável contador
seja populada com dados do for
, mas que exista fora desse laço, precisamos declará-la do lado de fora. Por isso, vamos manter o código como já havíamos desenvolvido anteriormente.
O laço for
é bem versátil! Conseguimos fazer vários tipos de operações matemáticas, expressões e até várias verificações com a declaração de mais de uma variável. Por isso que ele é tão usado em problemas de lógica de programação e algoritmos.
Vamos continuar praticando outros casos de laços de repetição no JavaScript para consolidar esses conceitos.
O curso Praticando JavaScript: laços de repetição possui 49 minutos de vídeos, em um total de 20 atividades. Gostou? Conheça nossos outros cursos de em Programação, ou leia nossos artigos de Programação.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
1 ano de Alura
Assine o PLUS e garanta:
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você tem acesso a eventos exclusivos, grupos de estudos e mentorias com especialistas de diferentes áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
1 ano de Alura
Todos os benefícios do PLUS e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Transforme a sua jornada com benefícios exclusivos e evolua ainda mais na sua carreira.
1 ano de Alura
Todos os benefícios do PRO e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.