200 Exercícios de JavaScript Fortaleça Suas Habilidades Com Desafios
200 Exercícios de JavaScript Fortaleça Suas Habilidades Com Desafios
Após a instalação, abra o VS Code. No início, você verá uma interface de usuário limpa e
organizada, dividida em várias seções:
Barra de atividades(1): Localizada no lado esquerdo da janela. Aqui, você pode
alternar entre diferentes vistas, como o explorador de arquivos, pesquisa, controle de
versão e extensões.
Editor de código(2): A área central é a mais ampla, onde você vai escrever e editar
seu código.
Painel de controle(3): Situado no lado direito, mostra detalhes e opções sobre o
arquivo ou a seleção atual.
Barra de status(4): Na parte inferior, fornece informações sobre o projeto atual e
permite que você acesse várias configurações e comandos.
Na imagem acima as áreas descritas estão determinadas, note que o editor está diferente do seu pois há um projeto
em andamento aberto.
O VS Code já vem com suporte para JavaScript por padrão, mas algumas extensões
podem melhorar ainda mais sua experiência de codificação. Para instalar uma extensão,
clique no ícone de extensões na barra de atividades e procure por estas extensões:
ESLint: Ajuda a identificar e corrigir problemas em seu código JavaScript.
Prettier: Um formatador de código que mantém seu código limpo e padronizado.
Visual Studio IntelliCode: Melhora a conclusão de código com inteligência artificial.
Para instalar, clique no botão "Install" na página da extensão. Uma vez instalada, a
extensão estará pronta para uso.
Processo de instalação das extensões.
O console do navegador é uma ferramenta poderosa que permite testar e depurar seu
código JavaScript. Aqui está um guia rápido sobre como acessar e usar o console do
navegador.
Para rodar JavaScript diretamente em seu navegador, você precisará criar um arquivo
HTML que referencia um arquivo JavaScript. Aqui está um passo a passo de como fazer
isso.
Agora, você precisará criar um arquivo JavaScript. No mesmo diretório do seu arquivo
HTML, crie um novo arquivo e salve-o com a extensão .js (por exemplo, main.js). Neste
arquivo, escreva algum código JavaScript. Por exemplo:
Em seguida, você precisará referenciar o arquivo JavaScript em seu arquivo HTML. Para
isso, adicione uma tag <script> com o atributo src apontando para o arquivo JavaScript,
logo antes do fechamento da tag </body>. Aqui está como o seu HTML ficará:
<!DOCTYPE html>
< html >
< head >
< title > Teste JavaScript </ title >
< script src= "main.js" ></ script >
</ head >
< body >
< h1 > Olá, Mundo! </ h1 >
</ body >
</ html >
Para ver o resultado do seu código JavaScript, abra o console do navegador. Você deve
ver a mensagem 'Olá, Console!'. E pronto! Agora você sabe como executar código
JavaScript em seu navegador.
Este processo deve ser repetido em todos os exemplos de código e exercícios ao longo
deste e-book. Organize os arquivos em uma pasta no seu computador para ser de fácil
acesso.
Com o tempo, você aprenderá a usar o JavaScript para manipular elementos HTML,
responder a eventos do usuário e muito mais!
Código de solução:
let idade = 25 ;
let peso = 70 ;
console .log( "Idade: " , idade);
console .log( "Peso: " , peso);
Explicação:
Este exercício envolve a declaração e inicialização de variáveis, e também a impressão
dos valores dessas variáveis no console. Aqui, let é usado para declarar variáveis idade e
peso, e então são atribuídos valores a elas. Em seguida, usamos o console.log() para
imprimir os valores das variáveis.
Código de solução:
const PI = 3.14159 ;
console .log( "PI: " , PI);
Explicação:
Neste exercício, estamos usando const para declarar uma constante. Diferente de uma
variável declarada com let, uma constante não pode ser reatribuída depois de ser
inicializada. Aqui, estamos atribuindo o valor de Pi à constante PI e, em seguida, usando
console.log() para imprimir seu valor.
Código de solução:
let númeroMáximo = Number .MAX_VALUE;
console .log( "Número Máximo: " , númeroMáximo);
Explicação:
JavaScript tem um valor máximo de número que pode ser representado, que é acessível
através da propriedade estática Number.MAX_VALUE. Aqui, estamos atribuindo esse
valor a uma variável chamada númeroMáximo e, em seguida, imprimindo-a usando
console.log().
Código de solução:
let nome = "João" ;
let sobrenome = "Silva" ;
let nomeCompleto = nome + " " + sobrenome;
console .log( "Nome Completo: " , nomeCompleto);
Explicação:
Este exercício é sobre a concatenação de strings. Declaramos duas variáveis, nome e
sobrenome, e as atribuímos a valores de string. Em seguida, declaramos uma terceira
variável, nomeCompleto, e atribuímos a ela a concatenação de nome e sobrenome com
um espaço entre elas. O operador + é usado para concatenar strings. Finalmente,
usamos console.log() para imprimir o nomeCompleto.
Código de solução:
let num1 = 10 ;
let num2 = 20 ;
let soma = num1 + num2;
console .log( "Soma: " , soma);
Explicação:
Declaramos duas variáveis, num1 e num2, e as atribuímos a valores numéricos. Em
seguida, declaramos uma terceira variável, soma, e atribuímos a ela a soma de num1 e
num2 usando o operador de adição (+). Por fim, usamos o console.log() para imprimir o
resultado.
Explicação:
Explicação:
Neste exercício, declaramos três variáveis numéricas, num1, num2 e num3. Em seguida,
usamos operadores de comparação para comparar os valores entre elas e imprimimos os
resultados. Usamos o operador < para verificar se num1 é menor que num2, o operador
> para verificar se num2 é maior que num3 e o operador == para verificar se num1 é
igual a num3.
Código de solução:
let num = 10 ;
num++;
console .log( "Número incrementado: " , num);
Explicação:
Neste exercício, declaramos uma variável num e a atribuímos a um valor numérico.
Usamos o operador de incremento ++ para aumentar o valor de num em 1. Por fim,
usamos console.log() para imprimir o resultado.
Operadores Condicionais
Descrição: Você precisará de uma função que receba um número como argumento.
Essa função usará estruturas if, else if e else para determinar e imprimir se o número é
positivo, negativo ou zero. Por exemplo, se recebermos o número 10, a saída deve ser
"positivo". Se recebermos -5, a saída deve ser "negativo". Se recebermos 0, a saída deve
ser "zero".
Código de solução:
function verificarNumero (num) {
if (num > 0 ) {
console .log( "O número é positivo" );
} else if (num < 0 ) {
console .log( "O número é negativo" );
} else {
console .log( "O número é zero" );
}
}
verificarNumero( 10 ); // Imprime: O número é positivo
verificarNumero( -5 ); // Imprime: O número é negativo
verificarNumero( 0 ); // Imprime: O número é zero
Descrição: Nesse exercício, você vai criar uma função que recebe duas notas, calcula a
média e, com base na média, decide se o aluno foi aprovado (média maior ou igual a 7)
ou reprovado (média menor que 7). Por exemplo, se as notas forem 8 e 6, a média será 7
e o aluno será aprovado.
Código de solução:
Exercício 11: Escreva um programa que verifica se uma pessoa pode votar
com base na idade.
Descrição: Nesse exercício, você vai criar uma função que recebe a idade de uma
pessoa e verifica se ela pode votar. No Brasil, o voto é obrigatório para pessoas entre 18 e
70 anos, facultativo para pessoas com 16 ou 17 anos ou acima de 70. Menores de 16 anos
não votam.
Código de solução:
Explicação: A função podeVotar recebe uma idade como argumento e, então, usa uma
estrutura de controle if/else if/else para determinar a obrigatoriedade do voto para essa
idade. Se a idade for maior ou igual a 18 e menor que 70, a função imprime "Voto
obrigatório.". Se a idade for maior ou igual a 16 e menor que 18, ou maior ou igual a 70,
a função imprime "Voto facultativo.". Caso contrário, a função imprime "Não vota.".
Quando chamamos a função com as idades 15, 16, 18 e 70, podemos ver essa lógica em
ação.
Descrição: Neste exercício, você vai criar uma função que recebe a média final de um
estudante e verifica sua situação, se aprovado (média igual ou superior a 7), se em
recuperação (média entre 5 e 6.9) ou se reprovado (média abaixo de 5).
Código de solução:
function situacaoEstudante (mediaFinal) {
if (mediaFinal >= 7 ) {
console .log( "Aprovado." );
} else if (mediaFinal >= 5 && mediaFinal < 7 ) {
console .log( "Em recuperação." );
} else {
console .log( "Reprovado." );
}
}
situacaoEstudante( 7 ); // Imprime: Aprovado.
situacaoEstudante( 6 ); // Imprime: Em recuperação.
situacaoEstudante( 4 ); // Imprime: Reprovado.
Descrição: Nesse exercício, você vai criar uma função que recebe o peso (em kg) e a
altura (em m) de uma pessoa, calcula o IMC e verifica em qual faixa o valor se encaixa.
As faixas são: abaixo do peso (IMC < 18.5), normal (18.5 ≤ IMC < 25), sobrepeso (25 ≤
IMC < 30) e obesidade (IMC ≥ 30).
Código de solução:
function calcularIMC (peso, altura) {
var imc = peso / (altura * altura);
if (imc < 18.5 ) {
console .log( "Abaixo do peso" );
} else if (imc >= 18.5 && imc < 25 ) {
console .log( "Peso normal" );
} else if (imc >= 25 && imc < 30 ) {
console .log( "Sobrepeso" );
} else {
console .log( "Obesidade" );
}
}
calcularIMC( 60 , 1.7 ); // Imprime: Peso normal
calcularIMC( 80 , 1.7 ); // Imprime: Sobrepeso
calcularIMC( 90 , 1.7 ); // Imprime: Obesidade
Descrição: Nesse exercício, você vai criar uma função que recebe um ano e verifica se
ele é bissexto. Um ano é bissexto se for divisível por 4, exceto os que são divisíveis por
100 mas não por 400.
Código de solução:
function verificarBissexto (ano) {
if ((ano % 4 == 0 && ano % 100 != 0 ) || (ano % 400 == 0 )) {
console .log(ano + " é um ano bissexto" );
} else {
console .log(ano + " não é um ano bissexto" );
}
}
verificarBissexto( 2000 ); // Imprime: 2000 é um ano bissexto
verificarBissexto( 2001 ); // Imprime: 2001 não é um ano bissexto
verificarBissexto( 2100 ); // Imprime: 2100 não é um ano bissexto
Descrição: Um palíndromo é uma palavra que tem a propriedade de poder ser lida
tanto da direita para a esquerda como da esquerda para a direita. Nesse exercício, você
irá criar uma função que recebe uma palavra como argumento e verifica se ela é um
palíndromo.
Código de solução:
function verificarPalindromo (palavra) {
var palavraInvertida = palavra.split( '' ).reverse().join( '' );
if (palavra == palavraInvertida) {
console .log(palavra + " é um palíndromo" );
} else {
console .log(palavra + " não é um palíndromo" );
}
}
verificarPalindromo( "arara" ); // Imprime: arara é um palíndromo
verificarPalindromo( "gato" ); // Imprime: gato não é um palíndromo
Descrição: Nesse exercício, você irá criar uma função que recebe três números como
argumentos e imprime o maior deles.
Código de solução:
function maiorNumero (n1, n2, n3) {
if (n1 > n2 && n1 > n3) {
console .log(n1 + " é o maior número" );
} else if (n2 > n1 && n2 > n3) {
console .log(n2 + " é o maior número" );
} else {
console .log(n3 + " é o maior número" );
}
}
maiorNumero( 1 , 2 , 3 ); // Imprime: 3 é o maior número
maiorNumero( 5 , 3 , 4 ); // Imprime: 5 é o maior número
maiorNumero( 7 , 8 , 7 ); // Imprime: 8 é o maior número
Descrição: Nesse exercício, você vai criar uma função que recebe um número como
argumento e imprime se ele é par ou ímpar.
Código de solução:
function parOuImpar (numero) {
if (numero % 2 == 0 ) {
console .log(numero + " é par" );
} else {
console .log(numero + " é ímpar" );
}
}
parOuImpar( 2 ); // Imprime: 2 é par
parOuImpar( 3 ); // Imprime: 3 é ímpar
Exercício 18: Escreva um programa que verifica se uma pessoa pode dirigir
com base na idade.
Descrição: Nesse exercício, você vai criar uma função que recebe a idade de uma
pessoa e verifica se ela pode dirigir. No Brasil, apenas pessoas com mais de 18 anos
podem tirar carteira de habilitação.
Código de solução:
function podeDirigir (idade) {
if (idade >= 18) {
console .log( "Pode dirigir." );
} else {
console .log( "Não pode dirigir" );
}
}
podeDirigir( 15 ); // Imprime: Não pode dirigir
podeDirigir( 18 ); // Imprime: Pode dirigir
podeDirigir( 36 ); // Imprime: Pode dirigir
Explicação: A função podeDirigir recebe uma idade como argumento e, então, usa
uma estrutura de controle if/else para determinar se a pessoa está apta a dirigir. Se a
idade for maior ou igual a 18, a função imprime "Pode dirigir.". Caso contrário, a função
imprime "Não pode dirigir.". Quando chamamos a função com as idades 15, 18 e 36,
podemos ver essa lógica em ação.
Exercício 19: Escreva um programa que verifica se um número está dentro
de um determinado intervalo.
Descrição: Neste exercício, você vai criar uma função que recebe três números como
argumentos: um número a ser verificado, o limite inferior e o limite superior do
intervalo. A função deve imprimir se o número está dentro do intervalo ou não.
Código de solução:
function dentroDoIntervalo (numero, limiteInferior, limiteSuperior) {
if (numero >= limiteInferior && numero <= limiteSuperior) {
console .log(numero + " está dentro do intervalo" );
} else {
console .log(numero + " está fora do intervalo" );
}
}
dentroDoIntervalo( 5 , 1 , 10 ); // Imprime: 5 está dentro do intervalo
dentroDoIntervalo( 15 , 1 , 10 ); // Imprime: 15 está fora do intervalo
Descrição: Neste exercício, você vai criar uma função que recebe uma nota de um
aluno como argumento e imprime uma classificação com base nessa nota.
Código de solução:
function classificarAluno (nota) {
if (nota >= 90 ) {
console .log( "A" );
} else if (nota >= 80 ) {
console .log( "B" );
} else if (nota >= 70 ) {
console .log( "C" );
} else if (nota >= 60 ) {
console .log( "D" );
} else {
console .log( "F" );
}
}
classificarAluno( 95 ); // Imprime: A
classificarAluno( 82 ); // Imprime: B
classificarAluno( 74 ); // Imprime: C
classificarAluno( 62 ); // Imprime: D
classificarAluno( 55 ); // Imprime: F
Descrição: Neste exercício, você criará uma função que recebe um número de 1 a 12
(representando os meses de janeiro a dezembro) e imprimirá a estação do ano
correspondente.
Código de solução:
function determinarEstacao (mes) {
if (mes < 3 || mes === 12 ) {
console .log( "Verão" );
} else if (mes < 6 ) {
console .log( "Outono" );
} else if (mes < 9 ) {
console .log( "Inverno" );
} else {
console .log( "Primavera" );
}
}
determinarEstacao( 12 ); // Imprime: Verão
determinarEstacao( 4 ); // Imprime: Outono
determinarEstacao( 7 ); // Imprime: Inverno
determinarEstacao( 10 ); // Imprime: Primavera
Descrição: Neste exercício, você criará uma função que recebe o número de um mês e
imprime o número de dias desse mês.
Código de solução:
function determinarDiasNoMes (mes) {
switch (mes) {
case 2 :
console .log( "28 ou 29 dias" );
break ;
case 4 :
case 6 :
case 9 :
case 11 :
console .log( "30 dias" );
break ;
default :
console .log( "31 dias" );
}
}
determinarDiasNoMes( 2 ); // Imprime: 28 ou 29 dias
determinarDiasNoMes( 4 ); // Imprime: 30 dias
determinarDiasNoMes( 1 ); // Imprime: 31 dias
Descrição: Neste exercício, você deve criar uma função que recebe uma cor, e imprime
no console o que essa cor representa, o console deve imprimir uma mensagem específica
para cores que não existem em um semáforo..
Código de solução:
function verificaSemafaro(cor) {
if (cor === "verde") {
console .log( "Siga em frente." );
} else if (cor === "amarelo") {
console .log( "Atenção, diminua a velocidade." );
} else if (cor === "vermelho") {
console .log( "Pare seu veículo." );
} else {
console .log( "Envie uma cor válida." );
}
}
verificaSemafaro( "verde" ); // Imprime: Siga em frente
verificaSemafaro( "amarelo" ); // Imprime: Atenção, diminua a velocidade
verificaSemafaro( "vermelho" ); // Imprime: Pare seu veículo
verificaSemafaro( "azul" ); // Impime: Envie uma cor válida
Explicação: A função varificaSemafaro recebe uma cor como argumento. Se a cor for
igual a verde, a função imprime 'Siga em frente.'. Se a cor for igual a amarelo, a função
imprime 'Atenção, diminua a velocidade.'. Se a cor for igual a vermelho, a função
imprime 'Pare seu veículo.'. Por fim, se for uma outra cor, a função imprime 'Envie uma
cor válida.'
L aços de Repetição
Os laços de repetição, também conhecidos como loops, são uma das principais
ferramentas em programação, permitindo que um bloco de código seja repetido diversas
vezes até que uma condição seja satisfeita. Eles são essenciais para a resolução de uma
grande variedade de problemas de programação, como a repetição de uma ação, a
iteração em uma coleção de itens ou a espera por uma condição ser satisfeita.
Em JavaScript, temos três estruturas principais de laços de repetição: for, while e do-
while. Cada uma tem suas particularidades e usos ideais, mas todas elas permitem
repetir um bloco de código baseado em uma condição.
Nesta seção, vamos explorar estes três tipos de laços através de vários exercícios práticos
e variados. Os exercícios foram planejados para abranger uma ampla gama de
problemas, desde a impressão de uma sequência de números até a criação de pequenos
jogos e operações com matrizes. Além disso, vamos também aprender a manipular e
transformar dados, como converter números decimais em binários e vice-versa.
Explicação: Este código inicia uma variável i em 1 e, enquanto i for menor ou igual a
10, imprime i no console e depois incrementa i em 1. O laço for é especialmente útil
quando sabemos exatamente quantas vezes queremos que nosso código seja executado.
Descrição: Neste exercício, você deve criar um loop usando a estrutura de repetição
while que percorra de 10 a 1 (em ordem decrescente) e imprima cada número no
console.
Código de solução:
let i = 10 ;
while (i >= 1 ){
console .log(i);
i--;
}
Explicação: Este código inicia uma variável i em 10 e, enquanto i for maior ou igual a
1, imprime i no console e depois decrementa i em 1. O laço while é útil quando não
sabemos exatamente quantas vezes o código precisa ser executado, mas temos uma
condição de parada definida.
Descrição: Neste exercício, você deve criar um loop usando a estrutura de repetição
do-while que percorra todos os números de 1 a 20 e imprima no console apenas os
números ímpares.
Código de solução:
let i = 1 ;
do {
if (i % 2 != 0 ){
console .log(i);
}
i++;
} while (i <= 20 );
Explicação: Este código inicia uma variável i em 1 e, enquanto i for menor ou igual a
20, verifica se i é ímpar (o resto da divisão de i por 2 é diferente de zero) e, se for,
imprime i no console. Depois, incrementa i em 1. O laço do-while garante que o bloco de
código seja executado pelo menos uma vez, antes de verificar a condição.
Descrição: Neste exercício, você deve criar um loop usando a estrutura de repetição for
que percorra de 1 a 10 e imprima a tabuada de multiplicação do número 5.
Código de solução:
for ( let i = 1 ; i <= 10 ; i++){
console .log( "5 x " + i + " = " + 5 *i);
}
Explicação: Este código inicia uma variável i em 1 e, enquanto i for menor ou igual a
10, imprime a multiplicação de 5 por i no console e depois incrementa i em 1. Usamos o
laço for, pois sabemos exatamente quantas vezes nosso código precisa ser executado (10
vezes).
Descrição: Neste exercício, você deve criar um loop usando a estrutura de repetição
while que percorra de 1 a 100 e calcule a soma de todos esses números.
Código de solução:
let i = 1 ;
let soma = 0 ;
while (i <= 100 ){
soma += i;
i++;
}
console .log(soma);
Explicação: Este código inicia uma variável i em 1 e uma variável soma em 0.
Enquanto i for menor ou igual a 100, adiciona i à soma e incrementa i em 1. Ao final,
imprime a soma no console. O laço while é útil quando não sabemos exatamente
quantas vezes o código precisa ser executado, mas temos uma condição de parada
definida.
Descrição: Neste exercício, você deve criar um loop usando a estrutura de repetição
do-while que percorra todos os números de 1 a 100 e imprima no console apenas os
números pares.
Código de solução:
let i = 1 ;
do {
if (i % 2 == 0 ){
console .log(i);
}
i++;
} while (i <= 100 );
Explicação: Este código inicia uma variável i em 1 e, enquanto i for menor ou igual a
100, verifica se i é par (o resto da divisão de i por 2 é igual a zero) e, se for, imprime i no
console. Depois, incrementa i em 1. O laço do-while garante que o bloco de código seja
executado pelo menos uma vez, antes de verificar a condição.
Explicação: Aqui temos um laço for externo que percorre os números de 2 a 100 e um
laço for interno que verifica se algum número entre 2 e o número em questão
(excluindo-o) é divisor desse número. Se encontrar algum divisor, a variável isPrime é
definida como false e o laço interno é interrompido. Se nenhum divisor for encontrado,
isPrime permanecerá true e o número será impresso.
Descrição: Neste exercício, você vai simular um jogo onde o usuário "pensa" em um
número de 1 a 100 e o programa deve adivinhar o número usando o método de busca
binária. Para simplificar, vamos supor que o número pensado pelo usuário é 50.
Código de solução:
let min = 1 ;
let max = 100 ;
let chute = Math .floor((max + min)/ 2 );
let numeroPensado = 50 ;
while (chute !== numeroPensado){
if (chute > numeroPensado){
max = chute;
}
else {
min = chute;
}
chute = Math .floor((max + min)/ 2 );
}
console .log( "O número pensado é: " + chute);
Explicação: Este código inicia com os valores mínimo e máximo possíveis para o
número pensado (1 e 100) e faz um "chute" no meio do intervalo. Enquanto o chute for
diferente do número pensado, ajusta o valor mínimo ou máximo de acordo com o chute
e faz um novo chute no meio do intervalo atualizado. Quando o chute é igual ao número
pensado, o laço termina e o número é impresso.
Explicação: Este código inicia com a escolha do usuário ("pedra") e escolhe uma
opção aleatória para o computador ("pedra", "papel" ou "tesoura"). Depois, verifica qual
opção ganha de acordo com as regras do jogo e define o resultado ("Usuário
Descrição: Neste exercício, você precisa imprimir os números de 1 a 100, mas com
uma condição especial. Se um número for múltiplo de 3, deve imprimir "Fizz" em vez do
número. Se for múltiplo de 5, deve imprimir "Buzz". E se for múltiplo de ambos (3 e 5),
deve imprimir "FizzBuzz".
Código de solução:
let num = 1 ;
while (num <= 100 ) {
if (num % 3 === 0 && num % 5 === 0 ) {
console .log( "FizzBuzz" );
}
else if (num % 3 === 0 ) {
console .log( "Fizz" );
}
else if (num % 5 === 0 ) {
console .log( "Buzz" );
}
else {
console .log(num);
}
num++;
}
Explicação: Este código inicia com um número igual a 1 e entra em um laço while que
continuará até que o número seja maior que 100. Dentro do laço, verifica se o número
atual é múltiplo de 3 e 5 (imprimindo "FizzBuzz" se for), múltiplo de 3 (imprimindo
"Fizz" se for), múltiplo de 5 (imprimindo "Buzz" se for) ou nenhum dos anteriores
(imprimindo o próprio número se for). Após cada verificação, incrementa o número.
Explicação: Este código usa um laço for para iterar de 1 a 10. Em cada iteração,
calcula o número triangular usando a fórmula n*(n+1)/2 e imprime o resultado.
Descrição: Neste exercício, você deve imprimir todos os números perfeitos de 1 a 100.
Um número é considerado perfeito se a soma de seus divisores, incluindo 1 mas não ele
mesmo, é igual ao próprio número. Por exemplo, o número 6 é perfeito, porque seus
divisores são 1, 2 e 3, e 1 + 2 + 3 = 6.
Código de solução:
for ( let i = 1 ; i <= 100 ; i++) {
let soma = 0 ;
for ( let j = 1 ; j < i; j++) {
if (i % j === 0 ) {
soma += j;
}
}
if (soma === i) {
console .log(i);
}
}
Explicação: Este código usa um laço for externo para iterar de 1 a 100. Em cada
iteração, inicia uma variável soma como 0 e então usa um laço for interno para iterar de
1 até i. Se i for divisível por j, j é somado à soma. Depois que o laço interno é concluído,
verifica se a soma é igual a i. Se for, imprime i como um número perfeito.
Exercício 37: Usando um laço while, imprima a soma dos quadrados dos
primeiros 10 números naturais.
Descrição: Neste exercício, você deve calcular e imprimir a soma dos quadrados dos
primeiros 10 números naturais. Os números naturais são os números positivos
começando em 1, então os primeiros 10 números naturais são 1, 2, 3, ..., 10, e os seus
quadrados são 1, 4, 9, ..., 100.
Código de solução:
let somaQuadrados = 0 ;
let i = 1 ;
while (i <= 10 ) {
somaQuadrados += i*i;
i++;
}
console .log(somaQuadrados);
Exercício 38: Usando um laço do-while, imprima a soma dos cubos dos
primeiros 10 números naturais.
Descrição: Neste exercício, você deve calcular e imprimir a soma dos cubos dos
primeiros 10 números naturais. Os números naturais são os números positivos
começando em 1, então os primeiros 10 números naturais são 1, 2, 3, ..., 10, e os seus
cubos são 1, 8, 27, ..., 1000.
Código de solução:
let somaCubos = 0 ;
let i = 1 ;
do {
somaCubos += i*i*i;
i++;
} while (i <= 10 );
console .log(somaCubos);
Exercício 39: Usando um laço for, crie um programa que calcule o fatorial
de um número.
Descrição: Neste exercício, você precisa criar um programa que calcula o fatorial de
um número. O fatorial de um número é o produto de todos os números inteiros
positivos de 1 até o número. Por exemplo, o fatorial de 5 (representado por 5!) é 1 * 2 * 3
* 4 * 5 = 120.
Código de solução:
Explicação: Nesse código, inicializamos a variável numero com o valor para o qual
desejamos calcular o fatorial e a variável fatorial com 1. O laço for percorre todos os
números de 1 até o número desejado, multiplicando o valor atual de fatorial por i. No
final, o código imprime o fatorial do número.
Exercício 40: Usando um laço while, crie um programa que inverta uma
string.
Descrição: Neste exercício, você precisa criar um programa que inverte uma string.
Por exemplo, a string "Hello" invertida se torna "olleH".
Código de solução:
let original = 'Hello' ; // Altere este valor para a string desejada.
let invertida = '' ;
let i = original.length - 1 ;
while (i >= 0 ) {
invertida += original[i];
i--;
}
console .log( `A string "${original}" invertida é "${invertida}"` );
Explicação: Nesse código, inicializamos a variável numero com o valor decimal que
queremos converter para binário e a variável binario com uma string vazia. O laço do-
while continua enquanto numero for maior que 0. Em cada iteração, calculamos o resto
da divisão de numero por 2 e o adicionamos ao início de binario. Então, atualizamos
numero para ser a parte inteira da divisão de numero por 2. No final, o código imprime
o número binário.
Explicação: Neste código, a variável binario é inicializada com o número binário que
queremos converter em decimal, e a variável decimal é inicializada como 0. O laço for
percorre a string binária de trás para frente. Em cada iteração, convertemos o caractere
binário atual em um número inteiro, multiplicamos por 2 elevado à potência do índice
(que começa do 0 e vai aumentando), e somamos ao valor de decimal. No final, o código
imprime o número decimal.
Descrição: Neste exercício, você deve criar um programa que soma duas matrizes. As
matrizes são listas bidimensionais de números. A soma de duas matrizes é obtida
somando os elementos correspondentes de cada matriz.
Código de solução:
let matriz1 = [[ 1 , 2 ], [ 3 , 4 ]]; // Altere estes valores para as matrizes
desejadas.
let matriz2 = [[ 5 , 6 ], [ 7 , 8 ]];
let soma = [];
let i = 0 ;
do {
let j = 0 ;
soma[i] = [];
do {
soma[i][j] = matriz1[i][j] + matriz2[i][j];
j++;
} while (j < matriz1[i].length);
i++;
} while (i < matriz1.length);
console .log( `A soma das matrizes é ${ JSON .stringify(soma)}` );
Descrição: Neste exercício, você deve escrever uma função simples que não recebe
argumentos e, quando chamada, imprime a frase "Olá, Mundo!".
Solução:
function imprimirOlaMundo () {
console .log( "Olá, Mundo!" );
}
imprimirOlaMundo();
Exercício 46: Escreva uma função que aceite dois números como
argumentos e retorne sua soma.
Descrição: Você deve escrever uma função que receba dois números como argumentos
e retorne a soma desses números.
Solução:
function somarNumeros (num1, num2) {
return num1 + num2;
}
console .log(somarNumeros( 3 , 4 )); // Saída: 7
Exercício 47: Escreva uma função que aceite um número como argumento
e retorne o seu quadrado.
Descrição: Neste exercício, você precisa escrever uma função que receba um número
como argumento e retorne o quadrado desse número (ou seja, o número multiplicado
por ele mesmo).
Solução:
function quadrado (num) {
return num * num;
}
console .log(quadrado( 5 )); // Saída: 25
Exercício 48: Escreva uma função que aceite um número como argumento
e retorne se ele é par ou ímpar.
Descrição: Neste exercício, você precisa escrever uma função que receba um número
como argumento e retorne uma string indicando se o número é par ou ímpar.
Solução:
function parOuImpar (num) {
if (num % 2 === 0 ) {
return 'par' ;
} else {
return 'ímpar' ;
}
}
console .log(parOuImpar( 5 )); // Saída: "ímpar"
Exercício 49: Escreva uma função que aceite três números como
argumentos e retorne o maior deles.
Descrição: Neste exercício, você precisa escrever uma função que receba três números
como argumentos e retorne o maior desses números.
Solução:
function maiorNumero (num1, num2, num3) {
return Math .max(num1, num2, num3);
}
console .log(maiorNumero( 3 , 5 , 4 )); // Saída: 5
Exercício 50: Escreva uma função que aceite uma string como argumento e
retorne a string invertida.
Descrição: Neste exercício, você precisa escrever uma função que receba uma string
como argumento e retorne a string com seus caracteres na ordem inversa.
Solução:
function inverterString (str) {
return str.split( '' ).reverse().join( '' );
}
console .log(inverterString( 'hello' )); // Saída: "olleh"
Explicação: A função inverterString recebe uma string str como argumento. A função
split('') é usada para converter a string em um array de caracteres. O método reverse() é
então usado para inverter a ordem dos elementos do array. Finalmente, o método join('')
é usado para combinar os elementos do array de volta em uma string.
Explicação: A função calcularFatorial começa por inicializar uma variável fatorial com
o valor 1. Em seguida, ela executa um laço for que começa em 2 e termina no número
dado, inclusive. A cada passagem pelo laço, o valor de i é multiplicado ao fatorial atual.
O fatorial final é então retornado.
Descrição: Um número é primo se for maior do que 1 e tiver apenas dois divisores
distintos: 1 e ele mesmo. Neste exercício, você deve escrever uma função que recebe um
número e retorna true se o número for primo e false caso contrário.
Solução:
function verificarPrimo (num) {
for ( let i = 2 ; i < num; i++) {
if (num % i === 0 ) {
return false ;
}
}
return num > 1 ;
}
console .log(verificarPrimo( 7 )); // Saída: true
Descrição: Neste exercício, você deve escrever uma função que receba um array de
números como argumento e retorne um novo array com os números ordenados em
ordem decrescente.
Solução:
function ordenarDecrescente (array) {
return array.sort((a, b) => b - a);
}
console .log(ordenarDecrescente([ 5 , 2 , 1 , 3 , 4 ])); // Saída: [5, 4, 3, 2,
1]
Descrição: Neste exercício, você deve criar uma função que aceita um array de
números como argumento e retorna o menor número desse array.
Solução:
function menorNumero (array) {
return Math .min(...array);
}
console .log(menorNumero([ 5 , 2 , 1 , 3 , 4 ])); // Saída: 1
Exercício 56: Escreva uma função que retorne o maior número em um array
de números.
Descrição: Neste exercício, você deve criar uma função que aceita um array de
números como argumento e retorna o maior número desse array.
Solução:
function maiorNumero (array) {
return Math .max(...array);
}
console .log(maiorNumero([ 5 , 2 , 1 , 3 , 4 ])); // Saída: 5
Exercício 57: Escreva uma função que retorne a soma de todos os números
ímpares em um array de números.
Descrição: Neste exercício, você deve criar uma função que aceita um array de
números como argumento e retorna a soma de todos os números ímpares desse array.
Solução:
function somaImpares (array) {
return array.reduce((soma, num) => num % 2 !== 0 ? soma + num : soma, 0
);
}
console .log(somaImpares([ 5 , 2 , 1 , 3 , 4 ])); // Saída: 9
Explicação: A função somaImpares usa o método reduce do array, que executa uma
função redutora para cada elemento do array, resultando em um único valor de saída. A
função redutora recebe a soma atual e o próximo número, e retorna a nova soma. Se o
número é ímpar (num % 2 !== 0), ele é adicionado à soma; caso contrário, a soma
permanece inalterada.
Exercício 58: Escreva uma função que retorne a soma de todos os números
pares em um array de números.
Descrição: Neste exercício, você deve criar uma função que aceita um array de
números como argumento e retorna a soma de todos os números pares desse array.
Solução:
function somaPares (array) {
return array.reduce((soma, num) => num % 2 === 0 ? soma + num : soma, 0
);
}
console .log(somaPares([ 5 , 2 , 1 , 3 , 4 ])); // Saída: 6
Descrição: Neste exercício, você deve criar uma função que receba um array de
números como argumento e retorne um novo array em que cada número seja duplicado.
Solução:
function duplicarNumeros (array) {
return array.map(num => num * 2 );
}
console .log(duplicarNumeros([ 5 , 2 , 1 , 3 , 4 ])); // Saída: [10, 4, 2, 6, 8]
Explicação: A função duplicarNumeros usa o método map do array, que cria um novo
array com o resultado da chamada de uma função para cada elemento do array. A
função passada para o map recebe um número e retorna o dobro desse número.
Descrição: Neste exercício, você deve criar uma função que receba um array de
números como argumento e retorne um novo array em que cada número seja elevado ao
quadrado.
Solução:
function quadradoNumeros (array) {
return array.map(num => num * num);
}
console .log(quadradoNumeros([ 5 , 2 , 1 , 3 , 4 ])); // Saída: [25, 4, 1, 9,
16]
Descrição: Neste exercício, você deve criar uma função que receba um array de
números como argumento e retorne um novo array em que cada número seja a raiz
quadrada do número original.
Solução:
function raizQuadradaNumeros (array) {
return array.map(num => Math .sqrt(num));
}
console .log(raizQuadradaNumeros([ 25 , 4 , 1 , 9 , 16 ])); // Saída: [5, 2, 1,
3, 4]
Descrição: Neste exercício, você deve criar uma função que receba um número como
argumento e retorne uma string que é repetida aquele número de vezes.
Solução:
function repetirString (num) {
return 'Olá ' .repeat(num);
}
console .log(repetirString( 3 )); // Saída: 'Olá Olá Olá'
Descrição: Neste exercício, você deve criar uma função que receba um número como
argumento e retorne um array com todos os números primos até aquele número.
Solução:
function primosAteN (num) {
let primos = [];
for ( let i = 2 ; i <= num; i++) {
if (isPrimo(i)) {
primos.push(i);
}
}
return primos;
}
function isPrimo (num) {
for ( let i = 2 ; i < num; i++) {
if (num % i === 0 ) {
return false ;
}
}
return num > 1 ;
}
console .log(primosAteN( 10 )); // Saída: [2, 3, 5, 7]
Explicação: A função primosAteN usa um loop for para verificar cada número até
num. Se o número é primo, ele é adicionado ao array primos. A função isPrimo é usada
para verificar se um número é primo. Ela usa um loop for para verificar se num é
divisível por qualquer número menor que ele. Se num é divisível por qualquer número,
ele não é primo e isPrimo retorna false. Se num não é divisível por nenhum número, ele
é primo e isPrimo retorna true.
Exercício 64: Escreva uma função que receba uma string e retorne o
número de palavras na string.
Descrição: Neste exercício, você deve criar uma função que receba uma string como
argumento e retorne o número de palavras na string.
Solução:
Explicação: A função contarPalavras usa o método split da string para dividir a string
em um array de palavras, onde cada palavra é separada por um espaço (' '). Em seguida,
usa a propriedade length do array para contar o número de palavras na string.
Exercício 65: Escreva uma função que aceite um array de números e uma
função de callback e retorne a soma de todos os números do array após a
aplicação da função de callback.
Descrição: Neste exercício, você deve criar uma função de alta ordem que receba um
array de números e uma função de callback como argumentos, e retorne a soma de todos
os números do array depois de aplicar a função de callback a cada número.
Solução:
function somaComCallback (array, callback) {
return array.map(callback).reduce((a, b) => a + b, 0 );
}
let numeros = [ 1 , 2 , 3 , 4 , 5 ];
let callback = num => num * 2 ;
console .log(somaComCallback(numeros, callback)); // Saída: 30
Exercício 66: Escreva uma função que aceite uma função de callback que
retorne verdadeiro ou falso e um array, e retorne um novo array que contém
apenas os elementos para os quais a função de callback retornou
verdadeiro.
Descrição: Neste exercício, você deve criar uma função de alta ordem que receba uma
função de callback e um array como argumentos, e retorne um novo array que contenha
apenas os elementos para os quais a função de callback retornou verdadeiro.
Solução:
Exercício 67: Escreva uma função que aceite uma função de callback e um
array de arrays, e retorne um novo array que contém os resultados de
aplicar a função de callback a cada array.
Descrição: Neste exercício, você deve criar uma função de alta ordem que receba uma
função de callback e um array de arrays como argumentos, e retorne um novo array que
contenha os resultados de aplicar a função de callback a cada array.
Solução:
function mapearArrays (array, callback) {
return array.map(callback);
}
let arrays = [[ 1 , 2 , 3 ], [ 4 , 5 , 6 ], [ 7 , 8 , 9 ]];
let callback = arr => arr.reduce((a, b) => a + b, 0 );
console .log(mapearArrays(arrays, callback)); // Saída: [6, 15, 24]
Explicação: A função mapearArrays usa o método map do array, que cria um novo
array com os resultados de chamar uma função de callback fornecida em cada elemento
do array. Neste caso, a função de callback soma todos os elementos de cada array.
Exercício 68: Escreva uma função de alta ordem que aceite um array de
números e uma função de callback, e retorne um novo array que contém
apenas os números do array original que satisfazem a condição da função
de callback.
Descrição: Neste exercício, você deve criar uma função de alta ordem que receba um
array de números e uma função de callback como argumentos, e retorne um novo array
que contenha apenas os números do array original que passam no teste implementado
pela função de callback.
Solução:
function filtrarNumeros (array, callback) {
return array.filter(callback);
}
let numeros = [ 1 , 2 , 3 , 4 , 5 ];
let callback = num => num > 3 ;
console .log(filtrarNumeros(numeros, callback)); // Saída: [4, 5]
Explicação: A função filtrarNumeros usa o método filter do array, que cria um novo
array com todos os elementos que passam no teste implementado pela função de
callback fornecida. Neste caso, a função de callback testa se um número é maior que 3.
Exercício 69: Escreva uma função que aceite um número e uma função de
callback, e execute a função de callback o número de vezes especificado.
Descrição: Neste exercício, você deve criar uma função de alta ordem que receba um
número e uma função de callback como argumentos, e execute a função de callback o
número de vezes especificado.
Solução:
function executarCallback (n, callback) {
for ( let i = 0 ; i < n; i++) {
callback(i);
}
}
let callback = i => console .log( `Execução ${i+ 1 }` );
executarCallback( 5 , callback); // Saída: "Execução 1", "Execução 2",
"Execução 3", "Execução 4", "Execução 5"
Exercício 70: Escreva uma função de alta ordem que aceite um array de
funções de callback e um valor, e retorne um array de resultados de aplicar
cada função de callback ao valor.
Descrição: Neste exercício, você deve criar uma função de alta ordem que receba um
array de funções de callback e um valor como argumentos, e retorne um array que
contenha os resultados de aplicar cada função de callback ao valor.
Solução:
function aplicarCallbacks (callback, valor) {
return callback.map(callback => callback(valor));
}
let callback = [num => num * 2 , num => num * num, num => num / 2 ];
let valor = 4 ;
console .log(aplicarCallbacks(callback, valor)); // Saída: [8, 16, 2]
Explicação: A função aplicarCallbacks usa o método map do array, que cria um novo
array com os resultados de chamar uma função de callback fornecida em cada elemento
do array. Neste caso, cada função de callback é aplicada ao valor fornecido.
Exercício 71: Escreva uma função que aceite uma função de callback e um
número, e execute a função de callback após um certo número de
milissegundos especificados pelo número.
Descrição: Neste exercício, você deve criar uma função de alta ordem que receba uma
função de callback e um número como argumentos, e execute a função de callback após
um certo número de milissegundos especificado pelo número. Isso é conhecido como
programação assíncrona.
Solução:
function executarDepois (callback, tempo) {
setTimeout(callback, tempo);
}
let callbaack = () => console .log( "Executado!" );
executarDepois(callbaack, 2000 ); // Saída: "Executado!" após 2 segundos
Descrição: Neste exercício, você deve criar uma função de alta ordem que receba um
número, um array de funções de callback e um valor inicial como argumentos, e retorne
o resultado final após a aplicação de todas as funções de callback no valor inicial, o
número de vezes especificado.
Solução:
function aplicarCallbacksNTimes (n, callback, valorInicial) {
let valor = valorInicial;
for ( let i = 0 ; i < n; i++){
callback.forEach(callback => {
valor = callback(valor);
});
}
return valor;
}
let callback = [num => num * 2 , num => num + 1 ];
let valorInicial = 1 ;
console .log(aplicarCallbacksNTimes( 2 , callback, valorInicial)); // Saída: 7
Exercício 73: Escreva uma função de alta ordem que aceite um número, um
array de funções de callback e um valor inicial, e retorne o resultado final
após a aplicação de todas as funções de callback no valor inicial, a cada "n"
milissegundos.
Descrição: Neste exercício, você deve criar uma função de alta ordem que receba um
número, um array de funções de callback e um valor inicial como argumentos, e retorne
o resultado final após a aplicação de todas as funções de callback no valor inicial, a cada
"n" milissegundos. Isso é conhecido como programação assíncrona.
Solução:
function aplicarCallbacksComIntervalo (n, callback, valorInicial) {
let valor = valorInicial;
let i = 0 ;
let intervalId = setInterval(() => {
if (i < callback.length) {
valor = callback[i](valor);
i++;
} else {
clearInterval(intervalId);
console .log(valor);
}
}, n);
}
let callback = [num => num * 2 , num => num + 1 ];
let valorInicial = 1 ;
aplicarCallbacksComIntervalo( 2000 , callback, valorInicial); // Saída: valor
após 2 segundos por callback
Exercício 74: Escreva uma função de alta ordem que aceite uma função de
callback e um array, e retorne um novo array que contém os resultados de
aplicar a função de callback a cada elemento do array, sem alterar o array
original.
Descrição: Neste exercício, você deve criar uma função de alta ordem que receba uma
função de callback e um array como argumentos, e retorne um novo array que contenha
os resultados de aplicar a função de callback a cada elemento do array. A função de
callback deve ser uma função pura, ou seja, não deve alterar o estado do array original.
Solução:
function mapearSemAlterar (array, callback) {
return array.map(callback);
}
let numeros = [ 1 , 2 , 3 , 4 , 5 ];
let callback = num => num * 2 ;
console .log(mapearSemAlterar(numeros, callback)); // Saída: [2, 4, 6, 8, 10]
console .log(numeros); // Saída: [1, 2, 3, 4, 5]
Exercício 75: Escreva uma função de alta ordem que aceite um array de
funções de callback e um valor, e retorne um novo array que contém os
resultados de aplicar a função de callback ao valor, na ordem inversa.
Descrição: Neste exercício, você deve criar uma função de alta ordem que receba um
array de funções de callback e um valor como argumentos, e retorne um novo array que
contenha os resultados de aplicar cada função de callback ao valor, na ordem inversa.
Solução:
function aplicarCallbacksInversamente (callback, valor) {
return callback.reverse().map(callback => callback(valor));
}
let callback = [num => num * 2 , num => num * num, num => num / 2 ];
let valor = 4 ;
console .log(aplicarCallbacksInversamente(callback, valor)); // Saída: [2,
16, 8]
Os Objetos são uma das estruturas de dados mais fundamentais em JavaScript, e uma
compreensão profunda de como eles funcionam é essencial para ser um bom
programador JavaScript.
Nesta seção, começaremos explorando o básico dos objetos - como definir e acessar
propriedades e métodos.
Então, entraremos em tópicos mais avançados como a herança de objetos, a cadeia de
protótipos e a diferença entre funções construtoras, classes e objetos literais.
Essas ferramentas e conceitos nos permitirão escrever código mais reutilizável e
eficiente.
Exercício 76: Crie um objeto vazio e adicione três propriedades a ele, cada
uma com diferentes tipos de valores.
Explicação: Nesse exercício, um objeto vazio foi criado com a sintaxe let obj = {};. Em
seguida, foram adicionadas três propriedades com diferentes tipos de valores. Para
adicionar uma propriedade a um objeto em JavaScript, basta utilizar a sintaxe
obj.nomeDaPropriedade = valor;. Ao final, imprimimos o objeto para visualizarmos as
propriedades adicionadas.
Descrição: Neste exercício, você vai criar um objeto que represente um livro. O objeto
deve ter propriedades para o título, autor e número de páginas. Além disso, o objeto
deve ter um método que imprima uma descrição do livro.
Solução:
let livro = {
titulo: 'O Hobbit' ,
autor: 'J.R.R. Tolkien' ,
numeroDePaginas: 310 ,
descricao: function () {
console .log( `O livro ${ this .titulo}, escrito por ${ this .autor}, tem
${ this .numeroDePaginas} páginas.` );
}
};
livro.descricao(); // Deve imprimir: 'O livro O Hobbit, escrito por J.R.R.
Tolkien, tem 310 páginas.'
Exercício 78: Crie um objeto "cachorro" com propriedades para raça, nome
e idade. Adicione um método que retorne a idade do cachorro em anos
humanos (idade do cachorro * 7).
Descrição: Neste exercício, você precisa criar um objeto que represente um cachorro.
Este objeto deve ter propriedades para raça, nome e idade. Em seguida, adicione um
método que converta a idade do cachorro em anos humanos (multiplique a idade do
cachorro por 7).
Solução:
let cachorro = {
raca: 'Labrador' ,
nome: 'Rex' ,
idade: 3 ,
idadeEmAnosHumanos: function () {
return this .idade * 7 ;
}
};
console .log(cachorro.idadeEmAnosHumanos()); // Deve imprimir: 21
Explicação: Neste exercício, foi criado um objeto cachorro com três propriedades:
raca, nome e idade. Além disso, foi adicionado um método idadeEmAnosHumanos que
retorna a idade do cachorro em anos humanos (a idade do cachorro multiplicada por 7).
Descrição: Neste exercício, você deve criar um objeto que represente um carro. O carro
deve ter propriedades para marca, modelo, ano e velocidade atual. Em seguida, adicione
os seguintes métodos ao objeto: um método que aumenta a velocidade atual, um método
que diminui a velocidade atual e um método que retorna a velocidade atual.
Solução:
let carro = {
marca: 'Ford' ,
modelo: 'Mustang' ,
ano: 1969 ,
velocidadeAtual: 0 ,
acelerar: function () {
this .velocidadeAtual += 10 ;
},
frear: function () {
this .velocidadeAtual -= 10 ;
if ( this .velocidadeAtual < 0 ) {
this .velocidadeAtual = 0 ;
}
},
obterVelocidadeAtual: function () {
return this .velocidadeAtual;
}
};
carro.acelerar();
console .log(carro.obterVelocidadeAtual()); // Deve imprimir: 10
carro.frear();
console .log(carro.obterVelocidadeAtual()); // Deve imprimir: 0
Explicação: Neste exercício, foi criado um objeto carro com quatro propriedades e
três métodos. As propriedades são marca, modelo, ano e velocidadeAtual. Os métodos
são acelerar, frear e obterVelocidadeAtual. O método acelerar aumenta a
velocidadeAtual em 10 unidades. O método frear diminui a velocidadeAtual em 10
unidades, mas garante que a velocidadeAtual nunca seja menor que 0. O método
obterVelocidadeAtual simplesmente retorna a velocidadeAtual.
Descrição: Neste exercício, você deve criar um objeto que represente um estudante. O
objeto estudante deve ter propriedades para o nome do estudante e as notas que ele
tirou em várias matérias. Em seguida, adicione um método ao objeto que calcule a
média das notas do estudante.
Solução:
let estudante = {
nome: 'João' ,
notas: [ 10 , 8 , 9 , 7 ],
calcularMedia: function () {
let soma = 0 ;
for ( let i = 0 ; i < this .notas.length; i++) {
soma += this .notas[i];
}
return soma / this .notas.length;
}
};
console .log(estudante.calcularMedia()); // Deve imprimir: 8.5
Explicação: Neste exercício, foi criado um objeto estudante com duas propriedades:
nome e notas. A propriedade notas é um array de números. Além disso, foi adicionado
um método calcularMedia que retorna a média das notas do estudante. Para calcular a
média, somamos todas as notas e dividimos pelo número de notas.
Exercício 81: Crie um objeto representando uma conta bancária, que possui
uma propriedade de saldo e métodos para depósito e saque.
Descrição: Neste exercício, você precisa criar um objeto que represente uma conta
bancária. Este objeto deve ter uma propriedade para o saldo e métodos para realizar um
depósito e um saque.
Solução:
let contaBancaria = {
saldo: 1000 ,
obterSaldo: function () {
return this .saldo;
}
};
contaBancaria.depositar( 500 );
console .log(contaBancaria.obterSaldo()); // Deve imprimir: 1500
contaBancaria.sacar( 200 );
console .log(contaBancaria.obterSaldo()); // Deve imprimir: 1300
Exercício 82: Crie um objeto "circulo" que possui uma propriedade de raio e
dois métodos que calculam a área e a circunferência.
Descrição: Neste exercício, você precisa criar um objeto que represente um círculo. O
círculo deve ter uma propriedade para o raio e dois métodos, um para calcular a área do
círculo (pi * raio^2) e outro para calcular a circunferência do círculo (2 * pi * raio).
Solução:
let circulo = {
raio: 5 ,
calcularArea: function () {
return Math .PI * Math .pow( this .raio, 2 );
},
calcularCircunferencia: function () {
return 2 * Math .PI * this .raio;
}
};
console .log(circulo.calcularArea()); // Deve imprimir: 78.53981633974483
console .log(circulo.calcularCircunferencia()); // Deve imprimir:
31.41592653589793
Explicação: Neste exercício, foi criado um objeto circulo com uma propriedade raio e
dois métodos: calcularArea e calcularCircunferencia. O método calcularArea retorna a
área do círculo, calculada como pi * raio^2. O método calcularCircunferencia retorna a
circunferência do círculo, calculada como 2 * pi * raio. Utilizamos o valor de pi
disponível na biblioteca Math do JavaScript.
Exercício 83: Crie um objeto "tempo" que possui propriedades para horas,
minutos e segundos, e um método para converter o tempo para segundos.
Descrição: Neste exercício, você precisa criar um objeto que represente um tempo. O
tempo deve ter propriedades para horas, minutos e segundos. Em seguida, adicione um
método ao objeto que converta o tempo para segundos.
Solução:
let tempo = {
horas: 2 ,
minutos: 30 ,
segundos: 15 ,
converterParaSegundos: function () {
return this .horas * 3600 + this .minutos * 60 + this .segundos;
}
};
console .log(tempo.converterParaSegundos()); // Deve imprimir: 9015
Explicação: Neste exercício, foi criado um objeto tempo com três propriedades: horas,
minutos e segundos. Além disso, foi adicionado um método converterParaSegundos que
retorna o tempo total em segundos. Para isso, multiplicamos as horas por 3600 (pois
uma hora tem 3600 segundos), os minutos por 60 (pois um minuto tem 60 segundos) e
somamos com os segundos.
Descrição: Neste exercício, você precisa criar um objeto que represente um retângulo. O
retângulo deve ter propriedades para a altura e a largura. Em seguida, adicione um
método ao objeto que calcule a área do retângulo.
Solução:
let retangulo = {
altura: 5 ,
largura: 10 ,
calcularArea: function () {
return this .altura * this .largura;
}
};
console .log(retangulo.calcularArea()); // Deve imprimir: 50
Explicação: Neste exercício, foi criado um objeto retangulo com duas propriedades:
altura e largura. Além disso, foi adicionado um método calcularArea que retorna a área
do retângulo, que é calculada multiplicando a altura pela largura.
Descrição: Neste exercício, você precisa criar um objeto que represente um quadrado.
Este objeto deve herdar as propriedades do objeto retangulo criado no exercício
anterior. Em seguida, substitua o método para calcular a área para que utilize apenas
uma das dimensões (já que a altura e a largura de um quadrado são iguais).
Solução:
let quadrado = Object .create(retangulo);
quadrado.largura = 5 ;
quadrado.altura = 5 ;
quadrado.calcularArea = function () {
return this .largura * this .largura;
};
console .log(quadrado.calcularArea()); // Deve imprimir: 25
Explicação: Neste exercício, foi criado um objeto quadrado que herda as propriedades
do objeto retangulo usando a função Object.create(). Em seguida, as propriedades
largura e altura do quadrado foram ajustadas para 5 (já que em um quadrado a largura e
a altura são iguais). Por fim, foi substituído o método calcularArea para que retorne a
área do quadrado, que é calculada multiplicando a largura pela largura (ou a altura pela
altura).
Exercício 86: Crie um objeto "livro" que possui propriedades para o título,
autor e número de páginas, e um método para exibir o livro na console.
Descrição: Neste exercício, você precisa criar um objeto que represente um livro. O
livro deve ter propriedades para o título, autor e número de páginas. Em seguida,
adicione um método ao objeto que exiba o livro na console no formato "Título, escrito
por Autor, com Páginas páginas".
Solução:
let livro = {
titulo: '1984' ,
autor: 'George Orwell' ,
paginas: 328 ,
exibirLivro: function () {
console .log( this .titulo + ', escrito por ' + this .autor + ', com ' +
this .paginas + ' páginas' );
}
};
livro.exibirLivro(); // Deve imprimir: 1984, escrito por George Orwell, com
328 páginas
Explicação: Neste exercício, foi criado um objeto livro com três propriedades: titulo,
autor e paginas. Além disso, foi adicionado um método exibirLivro que imprime o livro
na console no formato especificado no enunciado do exercício.
Exercício 87: Dado dois arrays, um com vários números pares e outro com
números ímpares, combine-os e, em seguida, filtre apenas os números que
são múltiplos de 5.
Descrição:
Você deve criar uma função que aceite dois arrays como argumento e retorne um novo
array resultante da combinação dos dois, mas filtrado para conter apenas múltiplos de 5.
Solução:
function combineAndFilter (pares, impares) {
return pares.concat(impares).filter(num => num % 5 === 0 );
}
const pares = [ 2 , 4 , 10 , 12 , 20 ];
const impares = [ 1 , 3 , 5 , 15 , 25 ];
console .log(combineAndFilter(pares, impares)); // [10, 20, 5, 15, 25]
Explicação:
Usamos o método concat() para combinar os dois arrays e o método filter() para filtrar
apenas os números múltiplos de 5.
Explicação:
Usamos o método map() para adicionar 10% a cada preço e o método reduce() para
somar os valores atualizados.
Exercício 89: Dada uma string com várias palavras separadas por espaços,
transforme-a em um array e depois retorne a palavra mais longa.
Descrição:
Você deve criar uma função que aceite uma string e retorne a palavra mais longa
encontrada.
Solução:
function longestWord (string) {
return string.split( " " ).reduce((acc, curr) => curr.length > acc.length
? curr : acc, "" );
}
const sentence = "Essa frase tem muitas palavras, qual é a maior?" ;
console .log(longestWord(sentence)); // "palavras"
Explicação:
Usamos o método split() para transformar a string em um array e reduce() para
encontrar a palavra mais longa.
Exercício 90: Dado um array que contém vários elementos duplicados, crie
uma função que remova todas as duplicatas e retorne um array com
elementos únicos.
Descrição:
Você deve criar uma função que aceite um array e retorne um novo array sem elementos
duplicados.
Solução:
function removeDuplicates (arr) {
return [...new Set (arr)];
}
const numbers = [ 1 , 2 , 3 , 2 , 4 , 3 , 5 , 6 , 7 , 5 , 8 ];
console .log(removeDuplicates(numbers)); // [1, 2, 3, 4, 5, 6, 7, 8]
Explicação:
O Set é uma estrutura de dados que armazena valores únicos. Ao passar o array para um
Set e então espalhá-lo de volta para um array, removemos todos os duplicados.
Descrição:
Você deve criar uma função que aceite um array de strings e retorne um novo array
ordenado pelo comprimento das strings.
Solução:
function sortByStringLength (arr) {
return arr.sort((a, b) => b.length - a.length);
}
const words = [ "apple" , "banana" , "cherry" , "date" , "elderberry" ];
console .log(sortByStringLength(words)); // ["elderberry", "banana",
"cherry", "apple", "date"]
Explicação:
O método sort() foi utilizado com uma função de comparação para ordenar o array com
base no comprimento das strings.
Exercício 92: Dado um array de objetos que têm várias propriedades, crie
uma função que retorne um novo array contendo apenas os valores de uma
propriedade específica.
Descrição:
Você deve criar uma função que aceite um array de objetos e uma chave de propriedade,
e retorne um novo array contendo os valores dessa propriedade.
Solução:
function extractPropertyValues (arr, key) {
return arr.map(obj => obj[key]);
}
const users = [
{name: "John" , age: 25 },
{name: "Jane" , age: 30 },
{name: "Doe" , age: 20 }
];
console .log(extractPropertyValues(users, "name" )); // ["John", "Jane",
"Doe"]
Explicação:
Utilizamos o método map() para extrair os valores da propriedade especificada de cada
objeto no array.
Descrição:
Você deve criar uma função que aceite um array de números e retorne a mediana.
Solução:
Explicação:
Primeiro, ordenamos o array. Se o comprimento do array for par, a mediana é a média
dos dois números do meio. Se for ímpar, a mediana é o número do meio.
Exercício 94: Dado um array de strings e um número n, retorne um novo
array contendo apenas as strings que têm mais de n caracteres.
Descrição:
Você deve criar uma função que aceite um array de strings e um número, e retorne um
novo array filtrado.
Solução:
function filterByStringLength (arr, n) {
return arr.filter(word => word.length > n);
}
const words = [ "apple" , "banana" , "cherry" , "date" , "elderberry" ];
console .log(filterByStringLength(words, 5 )); // ["banana", "elderberry"]
Explicação:
Usamos o método filter() para filtrar as strings cujo comprimento é maior que n.
Descrição:
Você deve criar uma função que aceite dois arrays e retorne um novo array que é a
concatenação de ambos.
Solução:
function concatenateArrays (arr1, arr2) {
return arr1.concat(arr2);
}
const firstArray = [ 1 , 2 , 3 ];
const secondArray = [ 4 , 5 , 6 ];
console .log(concatenateArrays(firstArray, secondArray)); // [1, 2, 3, 4, 5,
6]
Explicação:
O método concat() é usado para juntar dois ou mais arrays.
Explicação:
Convertendo ambos os arrays para strings usando join() e depois verificando a inclusão
usando includes().
Exercício 97: Dado um array, encontre o elemento que aparece mais vezes.
Descrição:
Você deve criar uma função que aceite um array e retorne o elemento mais frequente.
Solução:
function mostFrequentItem (arr) {
const frequency = {};
let maxCount = 0 ;
let mostFrequent;
for ( let item of arr) {
if (frequency[item]) {
frequency[item]++;
} else {
frequency[item] = 1 ;
}
if (frequency[item] > maxCount) {
maxCount = frequency[item];
mostFrequent = item;
}
}
return mostFrequent;
}
const numbers = [ 1 , 2 , 3 , 2 , 4 , 3 , 5 , 2 ];
console .log(mostFrequentItem(numbers)); // 2
Explicação:
A função usa um objeto para rastrear a frequência de cada elemento. Em seguida,
identifica o item com a contagem máxima.
Descrição:
Você deve criar uma função que aceite um array de strings e um array de palavras
proibidas, e retorne um novo array filtrado.
Solução:
function filterOutWords (words, forbiddenWords) {
return words.filter(word => !forbiddenWords.includes(word));
}
const allWords = [ "apple" , "banana" , "cherry" , "date" ];
const forbidden = [ "banana" , "date" ];
console .log(filterOutWords(allWords, forbidden)); // ["apple", "cherry"]
Explicação:
Usamos o método filter() para excluir palavras que estão presentes no array de palavras
proibidas.
Descrição:
Você deve criar uma função que aceite um array e retorne outro array com todos os
pares possíveis de elementos.
Solução:
function combineInPairs (arr) {
const result = [];
for ( let i = 0 ; i < arr.length; i++) {
for ( let j = i + 1 ; j < arr.length; j++) {
result.push([arr[i], arr[j]]);
}
}
return result;
}
const numbers = [ 1 , 2 , 3 , 4 ];
console .log(combineInPairs(numbers)); // [[1,2], [1,3], [1,4], [2,3], [2,4],
[3,4]]
Explicação:
Utilizamos dois loops for para criar todas as combinações possíveis de pares.
Descrição:
Você deve criar uma função que aceite um array e um número, e retorne um novo array
composto de sub-arrays.
Solução:
function chunkArray (arr, n) {
const chunks = [];
for ( let i = 0 ; i < arr.length; i += n) {
chunks.push(arr.slice(i, i + n));
}
return chunks;
}
const items = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 ];
console .log(chunkArray(items, 3 )); // [[1,2,3], [4,5,6], [7]]
Explicação:
Utilizamos um loop for para dividir o array original em sub-arrays de tamanho n usando
o método slice().
Descrição:
Você deve criar uma função que aceite um array de números e retorne a soma dos
números únicos.
Solução:
Explicação:
Usamos filter() para pegar números que aparecem apenas uma vez no array. Em
seguida, usamos reduce() para somar esses valores únicos.
Exercício 102: Dado um array de strings, retorne uma única string que é a
concatenação de todas as strings do array, separadas por vírgulas.
Descrição:
Você deve criar uma função que aceite um array de strings e retorne uma única string.
Solução:
function joinStrings (arr) {
return arr.join( "," );
}
const fruits = [ "apple" , "banana" , "cherry" ];
console .log(joinStrings(fruits)); // "apple,banana,cherry"
Explicação:
O método join() é usado para juntar todos os elementos de um array em uma string,
separados pelo delimitador fornecido.
JSON:
JavaScript Object Notation, conhecido por suas siglas JSON, tornou-se um dos formatos
de dados mais amplamente adotados na web. Em sua essência, o JSON é um formato
leve para intercâmbio de dados. Por ser um subconjunto da linguagem JavaScript, ele é
facilmente interpretado e gerado por muitas linguagens de programação modernas, o
que contribui para sua popularidade.
O JSON é frequentemente usado para transmitir dados entre um servidor e um cliente
na web, ou para armazenar configurações e informações em aplicativos. Por ser simples
e fácil de ler, muitos desenvolvedores preferem o JSON em detrimento de outros
formatos de intercâmbio de dados, como o XML.
Nesta seção, exploraremos as principais operações e manipulações relacionadas ao
JSON em JavaScript, ajudando a aprimorar sua capacidade de lidar com dados neste
formato. Desde a interpretação e criação de strings JSON até o manuseio de suas
estruturas internas, estes exercícios fornecerão as habilidades práticas necessárias para
operar com JSON de forma eficiente.
Descrição:
Utilize o método JSON.stringify() para converter um objeto em uma string JSON. Por
exemplo, o objeto { nome: "João", idade: 25 } deve ser convertido para a string
'{"nome":"João","idade":25}'.
Solução:
function objetoParaJson (obj) {
return JSON .stringify(obj);
}
const objetoTeste = { nome: "João" , idade: 25 };
console .log(objetoParaJson(objetoTeste)); // "{'nome':'João','idade':25}"
Explicação:
A função objetoParaJson recebe um objeto como argumento e utiliza a função
JSON.stringify() para convertê-lo em uma string JSON. O resultado é então retornado.
Descrição:
Utilize o método JSON.parse() para converter uma string em um objeto. Por exemplo, a
string '{"nome":"João","idade":25}' deve ser convertida para o objeto { nome: "João",
idade: 25 }.
Solução:
function jsonParaObjeto (jsonStr) {
return JSON .parse(jsonStr);
}
const jsonStringTeste = '{"nome":"João","idade":25}' ;
console .log(jsonParaObjeto(jsonStringTeste));
// {
// "nome": "João",
// "idade": 25
// }
Explicação:
A função jsonParaObjeto recebe uma string JSON como argumento e utiliza a função
JSON.parse() para convertê-la em um objeto JavaScript. O objeto resultante é então
retornado.
Descrição:
Dado uma string JSON que representa um objeto, converta essa string e acesse uma
propriedade específica do objeto convertido.
Solução:
function acessarPropriedade (jsonStr, prop) {
const obj = JSON .parse(jsonStr);
return obj[prop];
}
const jsonStringTeste = '{"nome":"João","idade":25}' ;
console .log(acessarPropriedade(jsonStringTeste, "nome" )); // "João"
Explicação:
A função acessarPropriedade primeiro converte a string JSON em um objeto JavaScript
e, em seguida, acessa a propriedade desejada do objeto, retornando o valor da
propriedade.
Descrição:
Depois de converter a string usando JSON.parse(), adicione uma nova propriedade ao
objeto e retorne o objeto atualizado.
Solução:
function adicionarPropriedade (jsonStr, chave, valor) {
const obj = JSON .parse(jsonStr);
obj[chave] = valor;
return obj;
}
const jsonStringTeste = '{"nome":"João","idade":25}' ;
console .log(adicionarPropriedade(jsonStringTeste, "profissao" , "Engenheiro"
));
// {
// "nome": "João",
// "idade": 25,
// "profissao": "Engenheiro"
// }
Explicação:
A função adicionarPropriedade converte a string JSON em um objeto JavaScript,
adiciona a nova propriedade ao objeto e retorna o objeto atualizado.
Descrição:
Use o segundo parâmetro da função JSON.stringify() para filtrar propriedades.
Solução:
function filtrarEConverter (obj) {
return JSON .stringify(obj, [ 'nome' , 'idade' ]);
}
const objetoTeste = { nome: "João" , senha: "12345" , idade: 25 };
console .log(filtrarEConverter(objetoTeste));
// "{'nome':'João','idade':25}"
Explicação:
A função filtrarEConverter usa o método JSON.stringify() para converter um objeto em
uma string JSON, mas o segundo parâmetro da função é usado para especificar quais
propriedades incluir na string resultante.
Descrição:
Utilize o terceiro parâmetro da função JSON.stringify() para adicionar espaços de
identação.
Solução:
function formatarJson (obj) {
return JSON .stringify(obj, null , 2 );
}
const objetoTeste = { nome: "João" , idade: 25 };
console .log(formatarJson(objetoTeste));
// "{
// 'nome': 'João',
// 'idade': 25
// }"
Explicação:
A função formatarJson converte o objeto em uma string JSON formatada com 2 espaços
de identação, usando o terceiro parâmetro de JSON.stringify().
Descrição:
Converta a string com JSON.parse(), adicione um novo objeto ao array e retorne o array
atualizado.
Solução:
function adicionarAoArray (jsonStr, novoObjeto) {
const arr = JSON .parse(jsonStr);
arr.push(novoObjeto);
return arr;
}
const jsonStringTeste = '[{"nome":"João","idade":25},
{"nome":"Maria","idade":30}]' ;
console .log(adicionarAoArray(jsonStringTeste, { nome: "Pedro" , idade: 22
}));
// [
// {
// nome: "João",
// idade: 25,
// },
// {
// nome: "Maria",
// idade: 30,
// },
// {
// nome: "Pedro",
// idade: 22,
// },
// ];
Explicação:
A função adicionarAoArray converte a string JSON em um array JavaScript, adiciona o
novo objeto ao array e retorna o array atualizado.
Descrição:
Use o segundo parâmetro da função JSON.stringify() para alterar valores.
Solução:
function alterarEConverter (obj) {
const alterarValor = (key, value) => {
if (key === "idade" ) return value + 1 ;
return value;
}
return JSON .stringify(obj, alterarValor);
}
const objetoTeste = { nome: "João" , idade: 25 };
console .log(alterarEConverter(objetoTeste));
// "{'nome':'João','idade':26}"
Explicação:
A função alterarEConverter utiliza a função alterarValor como o segundo parâmetro de
JSON.stringify(). Esta função modifica o valor da propriedade "idade", adicionando 1 à
idade original.
A evolução do JavaScript nunca para. Desde a sua criação em 1995, esta linguagem tem
crescido e se transformado constantemente, adaptando-se às necessidades de
desenvolvedores e às demandas das aplicações modernas. Uma das atualizações mais
significativas foi a introdução do ECMAScript 2015, comumente conhecido como ES6.
Esta versão trouxe consigo uma variedade de novos recursos, sintaxes e metodologias
que não só tornaram o JavaScript mais poderoso, mas também mais eficiente e legível.
ES6 foi um marco para a linguagem, estabelecendo o padrão para futuras atualizações.
Desde então, a cada ano, novas versões do ECMAScript têm sido lançadas, trazendo
melhorias incrementais e novas funcionalidades.
Neste capítulo, vamos mergulhar nos recursos mais influentes do ES6 e de versões
posteriores do ECMAScript. Abordaremos:
Let e Const: Novas formas de declarar variáveis que oferecem escopo de bloco
e imutabilidade.
Arrow Functions: Uma nova e mais concisa sintaxe para funções.
Classes: Uma abstração mais clara sobre protótipos, facilitando a criação de
objetos e herança.
Promises e Async/Await: Tornando o código assíncrono mais gerenciável e
legível.
Desestruturação: Uma maneira elegante de extrair valores de objetos e
arrays.
Parâmetros Rest e Spread: Trabalhando com quantidades indefinidas de
argumentos em funções.
E muitos outros recursos…
Cada uma destas características trouxe novas possibilidades e otimizações. Se você é
novo no ES6 ou deseja aprofundar seu conhecimento sobre as atualizações recentes do
JavaScript, este capítulo é para você. Vamos explorar juntos o moderno mundo do
JavaScript!
Template Literals
Exercício 111: Crie uma função que aceite nome, sobrenome e idade e
retorne uma apresentação usando template literals.
Descrição: A função deve retornar uma frase do tipo "Olá, meu nome é [nome]
[sobrenome] e tenho [idade] anos." usando template literals.
Solução:
function apresentacao (nome, sobrenome, idade) {
return `Olá, meu nome é ${nome} ${sobrenome} e tenho ${idade} anos.` ;
}
console .log(apresentacao( "João" , "Silva" , 30 )); // Saída: "Olá, meu nome
é João Silva e tenho 30 anos."
Exercício 112: Escreva uma função que aceite dois valores e retorne um
texto que faça uma comparação entre eles usando template literals.
Exercício 113: Crie uma função que aceite uma lista de itens e retorne uma
string enumerada usando template literals.
Descrição: A partir de um array como ['maçã', 'banana', 'uva'], a função deve retornar:
"1. maçã, 2. banana, 3. uva".
Solução:
function listaEnumerada (itens) {
return itens.map((item, index) => `${index + 1 }. ${item}` ).join( ', ' );
}
console .log(listaEnumerada([ 'maçã' , 'banana' , 'uva' ])); // Saída: "1.
maçã, 2. banana, 3. uva"
Explicação: Utilizamos o método map para criar um novo array com strings
formatadas usando template literals. Depois, join é usado para transformar o array em
uma única string.
Exercício 114: Crie uma função que aceite um objeto com informações de
um livro (título, autor e ano) e retorne uma descrição do livro usando
template literals.
Descrição: A partir de um objeto como { titulo: 'O Principe', autor: 'Maquiavel', ano:
1532 }, a função deve retornar: "O livro 'O Principe' foi escrito por Maquiavel em 1532."
Solução:
Arrow Functions
Descrição:
Dado uma função tradicional que aceita um nome como argumento e retorna uma
saudação, sua tarefa é convertê-la em uma arrow function.
Solução:
const helloWorld = name => `Hello, ${name}!` ;
// Testes
console .log(helloWorld( "Alice" )); // Esperado: "Hello, Alice!"
console .log(helloWorld( "Bob" )); // Esperado: "Hello, Bob!"
Explicação:
A arrow function permite uma sintaxe mais limpa e concisa. Usamos o template literal
(introduzido no ES6) para interpolar a string, o que torna o código ainda mais limpo e
fácil de ler.
Exercício 116: Escreva uma arrow function que aceite dois números como
argumentos e retorne sua multiplicação.
Descrição:
Crie uma função simples que multiplique dois números.
Solução:
const multiply = (a, b) => a * b;
// Testes
console .log(multiply( 5 , 4 )); // Esperado: 20
console .log(multiply( 3 , 7 )); // Esperado: 21
Explicação:
A arrow function toma dois parâmetros e simplesmente retorna o produto deles. Como é
uma expressão simples, o retorno é implícito.
Exercício 117: Escreva uma arrow function que não receba argumentos e
retorne a data atual.
Descrição:
Crie uma função que retorne o dia de hoje.
Solução:
Explicação:
A função arrow não recebe nenhum argumento (indicado por ()), e retorna a data atual
formatada como uma string legível.
Exercício 118: Crie uma arrow function que tome um array de números
como argumento e retorne a soma de todos eles.
Descrição:
Dado um array de números, retorne a soma total.
Solução:
const sumArray = numbers => numbers.reduce((acc, curr) => acc + curr, 0 );
// Testes
console .log(sumArray([ 1 , 2 , 3 , 4 ])); // Esperado: 10
console .log(sumArray([ 5 , 5 , 5 ])); // Esperado: 15
Explicação:
A função utiliza o método reduce dos arrays para acumular a soma. A arrow function é
usada dentro do reduce para simplificar a lógica de soma.
Exercício 119: Escreva uma arrow function que retorne uma mensagem
personalizada, dadas as propriedades "nome" e "idade" de um objeto.
Descrição:
Dado um objeto com propriedades "nome" e "idade", retorne uma mensagem
formatada.
Solução:
const personalizedMessage = ({ name, age }) => `Hello, my name is ${name}
and I am ${age} years old.` ;
// Testes
console .log(personalizedMessage({ name: "Alice" , age: 30 })); //
Esperado: "Hello, my name is Alice and I am 30 years old."
console .log(personalizedMessage({ name: "Bob" , age: 25 })); //
Esperado: "Hello, my name is Bob and I am 25 years old."
Explicação:
Esta arrow function utiliza a desestruturação de objetos para obter as propriedades
"name" e "age" diretamente como argumentos. Depois, usamos os template literals para
formatar e retornar a mensagem.
Exercício 120: Escreva uma arrow function que aceite um número como
argumento e retorne uma função que incrementa esse número.
Descrição:
O objetivo deste exercício é familiarizar-se com a capacidade das arrow functions de
retornar outras funções, criando um fechamento (closure).
Solução:
const incrementer = base => () => ++base;
// Testes
const incrementBy5 = incrementer( 5 );
console .log(incrementBy5()); // Esperado: 6
console .log(incrementBy5()); // Esperado: 7
Explicação:
A função externa incrementer recebe um número e retorna uma função interna sem
parâmetros. Esta função interna, quando chamada, incrementará o número fornecido à
função externa devido ao conceito de fechamento (closure).
Exercício 121: Escreva uma arrow function que aceite uma string e retorne
outra arrow function que aceite outra string. A função resultante deve
concatenar as duas strings.
Descrição:
Neste exercício, você trabalhará com arrow functions retornando outras arrow
functions.
Solução:
const concatFirstString = firstString => secondString => firstString +
secondString;
// Testes
const helloString = concatFirstString( "Hello " );
console .log(helloString( "World!" )); // Esperado: "Hello World!"
console .log(helloString( "Alice!" )); // Esperado: "Hello Alice!"
Explicação:
A função concatFirstString pega uma string e retorna outra função que, quando
chamada com uma segunda string, concatena a primeira e a segunda strings.
Exercício 122: Crie uma função que receba até três parâmetros, sendo os
dois primeiros obrigatórios e o terceiro opcional. Se o terceiro parâmetro
não for fornecido, atribua o valor "Desconhecido" a ele utilizando
parâmetros default.
Explicação: O código define uma função chamada informacoes que aceita três
parâmetros. O terceiro parâmetro, cidade, tem um valor default de "Desconhecido". Se a
função é chamada sem fornecer um valor para cidade, o valor default é usado.
Exercício 123: Desenvolva uma função que utilize o parâmetro rest para
receber um número indefinido de argumentos e retorne a soma de todos
eles.
Explicação: A função soma utiliza o parâmetro rest para coletar todos os argumentos
em um array chamado nums. Então, utiliza o método reduce para somar todos os
números contidos nesse array.
Exercício 124: Implemente uma função que aceite um objeto e use o
operador spread para criar uma cópia profunda desse objeto.
Explicação: A função copiaProfunda utiliza o operador spread para criar uma nova
cópia do objeto passado como argumento. A modificação feita no objeto original após a
cópia não afeta o objeto copiado.
Exercício 125: Escreva uma função que combine dois arrays em um novo
array. Use o operador spread para realizar essa tarefa.
Exercício 126: Crie uma função que aceite múltiplos argumentos utilizando
o parâmetro rest, e retorne um novo array contendo apenas os argumentos
que são números.
Exercício 127: Implemente uma função que aceite dois objetos. Use o
operador spread para mesclar os dois objetos em um novo objeto.
Descrição: O exercício ilustra como o operador spread pode ser usado para mesclar
dois objetos. O resultado é um novo objeto que combina propriedades de ambos os
objetos fornecidos.
Exercício 128: Crie uma função que utilize parâmetros default para criar um
objeto "carro" com propriedades marca, modelo e ano, onde apenas modelo
é obrigatório.
Explicação: A função criarCarro aceita três parâmetros e usa parâmetros default para
os parâmetros marca e ano. Se não forem fornecidos valores para marca e ano, eles
receberão "Desconhecido" e o ano atual, respectivamente.
Exercício 129: Implemente uma função que receba dois arrays e retorne um
novo array contendo os elementos do primeiro array seguido dos elementos
do segundo array. A função deve usar o parâmetro rest e o operador
spread.
Explicação: A função unirArrays utiliza o parâmetro rest para coletar todos os arrays
fornecidos em um único array. Em seguida, utiliza o operador spread juntamente com
concat para criar um novo array com todos os elementos dos arrays fornecidos.
Exercício 130: Crie uma função que use o operador spread para transformar
uma string em um array de caracteres.
Descrição: O operador spread pode ser usado não apenas em arrays e objetos, mas
também em strings, para transformá-las em arrays de caracteres individuais.
Exercício 131: Implemente uma função que aceite dois arrays. O primeiro
array é uma lista de objetos com uma chave e valor, e o segundo é uma
lista de chaves. A função deve retornar um novo array de objetos contendo
apenas as chaves especificadas no segundo array.
Descrição: Este exercício desafia os alunos a filtrar objetos com base em um conjunto
especificado de chaves. Através disso, eles aprenderão sobre a manipulação de
objetos e a importância de iterar corretamente sobre eles para alcançar o resultado
desejado.
function filtrarPorChaves (arrayObjetos, chaves) {
return arrayObjetos.map(obj => {
let novoObj = {};
chaves.forEach(chave => {
if (obj[chave] !== undefined ) novoObj[chave] = obj[chave];
});
return novoObj;
});
}
// Testes
const data = [{ nome: "Lucas" , idade: 30 , cidade: "São Paulo" }, { nome:
"Ana" , idade: 25 }];
console .log(filtrarPorChaves(data, [ "nome" , "cidade" ])); // [{ nome:
"Lucas", cidade: "São Paulo" }, { nome: "Ana" }]
Desestruturação (Destructuring)
A evolução constante das linguagens de programação muitas vezes revela recursos que
não apenas tornam a codificação mais eficiente, mas também mais legível e concisa. A
desestruturação, introduzida no ECMAScript 6, é um desses recursos notáveis para
JavaScript. Em sua essência, permite-nos "desmontar" estruturas de dados, como
objetos e arrays, em variáveis individuais, de uma maneira que é ao mesmo tempo
intuitiva e poderosa.
Antes desse recurso, se quiséssemos acessar valores dentro de um objeto ou array,
teríamos que acessá-los um por um, o que pode ser verboso, especialmente quando
lidamos com objetos aninhados ou arrays. Com a desestruturação, podemos extrair
múltiplas propriedades ou valores de uma vez, tornando nosso código mais limpo e mais
declarativo.
A desestruturação não é apenas uma ferramenta de conveniência; ela estabelece um
padrão que promove a clareza e a eficiência, permitindo que os desenvolvedores
trabalhem com dados de forma mais direta e menos propensa a erros.
Descrição: Dado um objeto com várias propriedades, extraia apenas o nome e a idade
desse objeto e retorne-os em uma string formatada.
function extrairDadosPessoa (pessoa) {
const { nome, idade } = pessoa;
return `Nome: ${nome}, Idade: ${idade}` ;
}
// Testes
const pessoa = { nome: "Lucas" , idade: 30 , cidade: "São Paulo" };
console .log(extrairDadosPessoa(pessoa)); // Nome: Lucas, Idade: 30
Descrição: Dado um array de números, extraia os três primeiros valores. Caso algum
valor não esteja presente, ele deve ser substituído por null.
function extrairValores (array) {
const [primeiro = null , segundo = null , terceiro = null ] = array;
return [primeiro, segundo, terceiro];
}
// Testes
console .log(extrairValores([ 1 , 2 ])); // [1, 2, null]
console .log(extrairValores([ 1 , 2 , 3 , 4 ])); // [1, 2, 3]
Descrição: Dado um objeto que tem uma propriedade chamada endereco, que por sua
vez é outro objeto contendo a propriedade cidade, extraia apenas a cidade desse objeto
aninhado.
function extrairCidade (usuario) {
const { endereco: { cidade } } = usuario;
return cidade;
}
// Testes
const usuario = { nome: "Lucas" , endereco: { rua: "Rua A" , cidade: "São
Paulo" , estado: "SP" } };
console .log(extrairCidade(usuario)); // São Paulo
Descrição: Dado um objeto com propriedades nome e idade, escreva uma função que
desestruture essas propriedades diretamente em seus parâmetros e retorne uma string
formatada.
function exibirInformacoes ({ nome, idade }) {
return `Nome: ${nome}, Idade: ${idade}` ;
}
// Testes
const pessoa2 = { nome: "Ana" , idade: 25 };
console .log(exibirInformacoes(pessoa2)); // Nome: Ana, Idade: 25
Descrição: Escreva uma função que aceite vários números como argumentos. Extraia
os três primeiros números e coloque os restantes em um array separado.
function separarNumeros (primeiro, segundo, terceiro, ...resto) {
return [primeiro, segundo, terceiro, resto];
}
// Testes
console .log(separarNumeros( 1 , 2 , 3 , 4 , 5 , 6 )); // [1, 2, 3, [4, 5, 6]]
Descrição: Sem usar uma variável temporária, troque os valores de duas variáveis.
let a = 5 ;
let b = 10 ;
[a, b] = [b, a];
// Testes
console .log(a); // 10
console .log(b); // 5
Descrição: Dado um array de arrays, extraia o segundo valor do primeiro array interno
e o primeiro valor do segundo array interno.
Descrição: Crie uma classe Tempo com propriedades para horas, minutos e segundos.
Adicione métodos para somar e subtrair outro objeto Tempo.
class Tempo {
constructor (horas = 0, minutos = 0, segundos = 0) {
this .horas = horas;
this .minutos = minutos;
this .segundos = segundos;
}
somar(tempo) {
let totalSegundos = this .segundos + tempo.segundos;
let totalMinutos = this .minutos + tempo.minutos;
let totalHoras = this .horas + tempo.horas;
if (totalSegundos >= 60 ) {
totalMinutos += Math .floor(totalSegundos / 60 );
totalSegundos %= 60 ;
}
if (totalMinutos >= 60 ) {
totalHoras += Math .floor(totalMinutos / 60 );
totalMinutos %= 60 ;
}
return new Tempo(totalHoras, totalMinutos, totalSegundos);
}
subtrair(tempo) {
let totalSegundos = this .segundos - tempo.segundos;
let totalMinutos = this .minutos - tempo.minutos;
let totalHoras = this .horas - tempo.horas;
if (totalSegundos < 0 ) {
totalMinutos -= Math .ceil( Math .abs(totalSegundos) / 60 );
totalSegundos = 60 - ( Math .abs(totalSegundos) % 60 );
}
if (totalMinutos < 0 ) {
totalHoras -= Math .ceil( Math .abs(totalMinutos) / 60 );
totalMinutos = 60 - ( Math .abs(totalMinutos) % 60 );
}
return new Tempo(totalHoras, totalMinutos, totalSegundos);
}
}
// Testes
const tempo1 = new Tempo( 1 , 20 , 30 );
const tempo2 = new Tempo( 0 , 50 , 40 );
let resultado = tempo1.somar(tempo2);
console .log(
`${resultado.horas}h:${resultado.minutos}m:${resultado.segundos}s` ); //
2h:11m:10s
resultado = tempo1.subtrair(tempo2);
console .log(
`${resultado.horas}h:${resultado.minutos}m:${resultado.segundos}s` ); //
0h:29m:50s
Descrição: Simulando interfaces, crie duas classes, Voador e Nadador, cada uma
com um método, voar e nadar, respectivamente. Em seguida, crie uma classe Pato que
"implemente" ambas as "interfaces", fazendo a classe Pato ter os métodos das duas
classes anteriores.
class Voador {
voar() {
return "Estou voando!" ;
}
}
class Nadador {
nadar() {
return "Estou nadando!" ;
}
}
class Pato extends Voador {
constructor () {
super ();
// "Implementando" o método nadar do Nadador
const nadador = new Nadador();
this .nadar = nadador.nadar.bind( this );
}
}
// Testes
const pato = new Pato();
console .log(pato.voar()); // Estou voando!
console .log(pato.nadar()); // Estou nadando!
Explicação: A classe Pato estende a classe Voador, herdando seu método voar. Para
"implementar" o método nadar da classe Nadador, criamos uma instância de Nadador
dentro do construtor de Pato e associamos o método nadar a this. O uso de bind garante
que o contexto de this seja o objeto Pato ao invocar o método.
Descrição: Crie uma classe Animal com um método falar que retorna "O animal faz
um som". Em seguida, crie duas subclasses: Cão e Gato. Ambas devem sobrescrever o
método falar, retornando "O cão late" e "O gato mia", respectivamente.
class Animal {
falar() {
return "O animal faz um som" ;
}
}
class C ã o extends Animal {
falar() {
return "O cão late" ;
}
}
class Gato extends Animal {
falar() {
return "O gato mia" ;
}
}
// Testes
const cão = new Cão();
console .log(cão.falar()); // O cão late
const gato = new Gato();
console .log(gato.falar()); // O gato mia
Descrição: Crie uma classe abstrata chamada Forma com um método abstrato
area. Crie duas subclasses: Círculo e Retângulo, que implementam o método area.
class Forma {
area() {
throw new Error ( "Método 'area' deve ser implementado por
subclasses!" );
}
}
class C í rculo extends Forma {
constructor (raio) {
super ();
this .raio = raio;
}
area() {
return Math .PI * this .raio * this .raio;
}
}
class Ret â ngulo extends Forma {
constructor (largura, altura) {
super ();
this .largura = largura;
this .altura = altura;
}
area() {
return this .largura * this .altura;
}
}
// Testes
const círculo = new Círculo( 5 );
console .log(círculo.area()); // 78.53981633974483
const retângulo = new Retângulo( 4 , 6 );
console .log(retângulo.area()); // 24
Explicação: A classe Forma simula ser uma classe abstrata ao lançar um erro no
método area. As subclasses Círculo e Retângulo implementam esse método para calcular
suas respectivas áreas.
Descrição: Crie uma classe Pessoa que encapsule a idade da pessoa, garantindo
que a idade não possa ser negativa.
class Pessoa {
constructor (nome, idade) {
this .nome = nome;
this ._idade = idade;
}
get idade() {
return this ._idade;
}
set idade(valor) {
if (valor < 0 ) {
console .log( "Idade não pode ser negativa!" );
return ;
}
this ._idade = valor;
}
}
// Testes
const pessoa = new Pessoa( "João" , 30 );
console .log(pessoa.idade); // 30
pessoa.idade = -5 ; // Idade não pode ser negativa!
console .log(pessoa.idade); // 30
Explicação: A classe Pessoa usa o método get e set para criar um acessador de
propriedade chamado idade. Isso permite validar os valores definidos e garantir que a
idade nunca seja negativa.
Descrição: Crie uma classe Vendedor que estenda uma classe Pessoa. O Vendedor
deve ter um método vender e uma propriedade totalVendas, que é incrementada a cada
venda.
class Pessoa {
constructor (nome) {
this .nome = nome;
}
falar() {
return `${ this .nome} está falando.` ;
}
}
class Vendedor extends Pessoa {
constructor (nome) {
super (nome);
this .totalVendas = 0 ;
}
vender() {
this .totalVendas++;
return `${ this .nome} fez uma venda.` ;
}
}
// Testes
const vendedor = new Vendedor( "Carlos" );
console .log(vendedor.vender()); // Carlos fez uma venda.
console .log(vendedor.totalVendas); // 1
Explicação: A classe Vendedor estende a classe Pessoa. Ele herda o método falar e
adiciona seu próprio método vender e a propriedade totalVendas.
Descrição: Crie uma classe Calculadora que tenha um método estático somar, que
aceite dois números e retorne sua soma.
class Calculadora {
static somar(a, b) {
return a + b;
}
}
// Testes
console .log(Calculadora.somar( 5 , 3 )); // 8
Explicação: A classe Calculadora tem um método estático chamado somar.
Métodos estáticos pertencem à classe e não à instância da classe. Eles são
chamados no próprio nome da classe, como demonstrado no teste.
Descrição: Crie uma classe Carro que possui um método de fábrica criarSedan que
retorna uma nova instância de um carro com a propriedade tipo definida como 'Sedan'.
class Carro {
constructor (tipo) {
this .tipo = tipo;
}
static criarSedan() {
return new Carro( 'Sedan' );
}
}
// Testes
const sedan = Carro.criarSedan();
console .log(sedan.tipo); // Sedan
Explicação: A classe Carro tem um método estático chamado criarSedan, que atua
como um método de fábrica. Ele cria e retorna uma nova instância da classe Carro com o
tipo definido como 'Sedan'.
Exercício 148 - Classes e Exceções
Descrição: Crie uma classe Conta com um método sacar. Se o valor do saque for
maior que o saldo disponível, lance uma exceção.
class Conta {
constructor (saldo) {
this .saldo = saldo;
}
sacar(valor) {
if (valor > this .saldo) {
throw new Error ( 'Saldo insuficiente.' );
}
this .saldo -= valor;
return this .saldo;
}
}
// Testes
const conta = new Conta( 100 );
console .log(conta.sacar( 50 )); // 50
try {
conta.sacar( 100 );
} catch (e) {
console .log(e.message); // Saldo insuficiente.
}
Explicação: A classe Conta tem um método sacar que verifica se o valor de saque é
maior que o saldo disponível. Se for, ele lança uma exceção, caso contrário, ele deduz o
valor do saldo e retorna o novo saldo.
Descrição: Crie uma classe Segredo que tenha um método privado chamado
_mensagemSecreta e um método público para acessar essa mensagem.
class Segredo {
#mensagemSecreta = "Esta é uma mensagem secreta!" ;
revelarSegredo() {
return this .#mensagemSecreta;
}
}
// Testes
const segredo = new Segredo();
console .log(segredo.revelarSegredo()); // Esta é uma mensagem secreta!
Descrição: Crie uma classe Veículo com um construtor que aceite marca e modelo.
Em seguida, crie uma classe Carro que herde de Veículo e adicione um construtor que
aceite marca, modelo e numPortas.
class Ve í culo {
constructor (marca, modelo) {
this .marca = marca;
this .modelo = modelo;
}
}
class Carro extends Ve í culo {
constructor (marca, modelo, numPortas) {
super (marca, modelo);
this .numPortas = numPortas;
}
}
// Testes
const carro = new Carro( "Toyota" , "Corolla" , 4 );
console .log(carro); // { marca: 'Toyota', modelo: 'Corolla', numPortas: 4 }
Promises e Async/Await
Exercício 151: Implemente uma função que retorne uma Promise que
resolve após um tempo específico em milissegundos.
Descrição: Este exercício testa a habilidade de criar uma Promise que utiliza o
setTimeout para resolver após um determinado período.
Solução com testes:
function delay (ms) {
return new Promise (resolve => setTimeout(resolve, ms));
}
// Teste
delay( 1000 ).then(() => console .log( 'Resolvido após 1 segundo!' ));
Explicação: A função delay retorna uma Promise que se resolve após um tempo
determinado por ms graças ao setTimeout. A função setTimeout é chamada com a
função resolve da Promise e o tempo em milissegundos, garantindo que a Promise seja
resolvida após esse período.
Exercício 152: Crie uma função assíncrona que simule a busca de dados de
um banco de dados e lance um erro se a entrada for uma string específica.
Descrição: O objetivo é simular uma operação assíncrona que pode falhar com base
em determinadas entradas.
Solução com testes:
async function fetchData (input) {
if (input === "error" ) {
throw new Error ( "Entrada inválida!" );
}
return `Dados para ${input}` ;
}
// Teste
fetchData( "data" )
.then(data => console .log(data))
.catch(err => console .error(err.message));
fetchData( "error" )
.then(data => console .log(data))
.catch(err => console .error(err.message));
Explicação: A função fetchData verifica se a entrada é a string "error". Se for, ela lança
um erro; caso contrário, ela retorna os dados. Como é uma função assíncrona, ela
retornará implicitamente uma Promise.
Exercício 154: Implemente uma função assíncrona que use try/catch para
lidar com erros ao esperar uma Promise.
Descrição: Esse exercício visa aprimorar a habilidade de lidar com erros em funções
assíncronas.
Solução com testes:
Descrição: Este exercício visa aprimorar a habilidade de fazer uma chamada de API
usando async/await e de tratar possíveis erros.
Solução com testes:
async function fetchDataFromAPI (url) {
let response = await fetch(url);
if (response.status !== 200 ) {
throw new Error ( "Falha na obtenção dos dados" );
}
return await response.json();
}
// Teste (este é apenas um exemplo, e o URL pode precisar ser modificado)
fetchDataFromAPI( "https://api.example.com/data" )
.then(data => console .log(data))
.catch(err => console .error(err.message));
Exercício 156: Crie uma função que aguarde várias Promises e retorne a
primeira que for resolvida.
Explicação: Promise.race é usado para retornar a primeira Promise que for resolvida
(ou rejeitada) entre as Promises fornecidas.
Exercício 157: Crie uma função async que simule a recuperação de dois
recursos de API em sequência, onde o segundo requer dados do primeiro.
Explicação: A classe DataLoader tem um método loadData que usa async/await para
carregar dados de uma API e armazená-los na propriedade data da classe.
Exercício 159: Crie uma função que retorna uma Promise que rejeita após
um tempo específico em milissegundos.
Descrição: Este exercício visa testar a capacidade de criar Promises que podem ser
rejeitadas após um certo tempo.
Solução com testes:
function rejectAfterDelay (ms) {
return new Promise ((_, reject) => setTimeout(() => reject( new Error (
"Rejeitado após timeout!" )), ms));
}
// Teste
rejectAfterDelay( 1000 ).catch(err => console .error(err.message)); // Deve
imprimir "Rejeitado após timeout!"
Explicação: Usamos um loop for...of para processar uma série de URLs em sequência.
Para cada URL, esperamos que os dados sejam carregados antes de continuar para a
próxima.
Iteradores e Geradores
function * fibonacci () {
let [prev, curr] = [ 0 , 1 ];
while ( true ) {
yield curr;
[prev, curr] = [curr, prev + curr];
}
}
// Testes
const fib = fibonacci();
console .log(fib.next().value); // 1
console .log(fib.next().value); // 1
console .log(fib.next().value); // 2
console .log(fib.next().value); // 3
Explicação:
A função geradora produz valores da sequência Fibonacci indefinidamente. Começamos
com os dois primeiros números da sequência (0 e 1). A cada chamada do next, nós
retornamos o valor atual e atualizamos nossas variáveis para o próximo número da
sequência.
Exercício 162: Utilize um gerador para criar um iterável que gere uma
sequência aritmética, dado um valor inicial, uma razão e o número de
termos.
Descrição: O gerador deve aceitar três parâmetros e produzir uma sequência
aritmética baseada nos inputs fornecidos.
Solução:
Explicação:
A função geradora começa com o valor inicial e adiciona a razão a cada iteração até que
a sequência tenha o tamanho desejado.
Exercício 163: Implemente um gerador que atue como uma paginação para
um array, retornando os itens em lotes.
Explicação:
Usamos o método slice para pegar lotes do array baseados no índice atual e no tamanho
do lote.
Explicação:
A função isPrime é usada para verificar se um número é primo. O gerador começa em 2
(o primeiro número primo) e verifica cada número em sequência para determinar se é
primo, retornando os que são.
Explicação:
Primeiro, separamos os números em pares e ímpares usando o método filter. Em
seguida, alternamos entre os dois arrays para produzir os números desejados.
Explicação:
A função geradora começa com o valor inicial a e multiplica pelo valor da razão r a cada
iteração, até que a sequência atinja o tamanho desejado.
Descrição: A função range em Python aceita até 3 argumentos: start, stop, e step. Crie
um gerador que imite essa funcionalidade.
Solução:
function * range (start, stop = null, step = 1 ) {
if (stop === null ) {
stop = start;
start = 0 ;
}
for ( let i = start; i < stop; i += step) {
yield i;
}
}
// Testes
console .log([...range( 5 )]); // [0, 1, 2, 3, 4]
console .log([...range( 2 , 5 )]); // [2, 3, 4]
console .log([...range( 0 , 10 , 2 )]); // [0, 2, 4, 6, 8]
Explicação:
Esta função geradora mimetiza a funcionalidade da função range do Python. Se apenas
um valor for passado, ele será tratado como o valor de parada, com o início padrão em 0.
Caso contrário, ela seguirá os argumentos de início, parada e passo fornecidos.
Explicação:
Criamos um array de iteradores para cada iterável de entrada. Em cada iteração,
recuperamos o próximo valor de cada iterador e verificamos se algum dos iteradores foi
concluído. Se um iterador estiver concluído, encerramos o loop. Caso contrário,
retornamos uma tupla de valores.
Exercício 169: Crie um gerador que gere uma série Fibonacci até um
número máximo n.
Descrição: O gerador deve produzir a série Fibonacci até que o valor ultrapasse um
limite n fornecido.
Solução:
function * fibonacci (n) {
let [prev, curr] = [ 0 , 1 ];
while (curr <= n) {
yield curr;
[prev, curr] = [curr, prev + curr];
}
}
// Testes
console .log([...fibonacci( 100 )]); // [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
Explicação:
Utilizamos a desestruturação de arrays para trocar facilmente os valores prev e curr a
cada iteração, produzindo assim a série Fibonacci. O loop continua até que o valor
ultrapasse o limite n fornecido.
Explicação:
O gerador itera sobre cada valor do iterável de entrada, retornando uma tupla contendo
o índice atual e o valor.
Explicação:
A função geradora começa com o valor inicial a e adiciona a diferença d a cada iteração,
até que a sequência atinja o tamanho desejado.
Descrição: Dado um array de números, utilize o método filter para retornar apenas
os números ímpares.
Solução com testes:
function filterOdd (numbers) {
return numbers.filter(n => n % 2 !== 0 );
}
console .log(filterOdd([ 1 , 2 , 3 , 4 , 5 ])); // [1, 3, 5]
console .log(filterOdd([ 10 , 12 , 15 ])); // [15]
Explicação: A função filterOdd faz uso do método filter para retornar todos os
números ímpares no array. O método filter cria um novo array com todos os elementos
que passam no teste da função fornecida.
Descrição: Usando o método find, procure o primeiro número no array que seja
maior que 10.
Solução com testes:
Descrição: Dado um array de números, utilize o método map para dobrar todos os
valores do array.
Solução com testes:
function doubleValues (numbers) {
return numbers.map(n => n * 2 );
}
console .log(doubleValues([ 1 , 2 , 3 , 4 ])); // [2, 4, 6, 8]
Explicação: A função doubleValues usa o método map para dobrar cada número no
array. O método map cria um novo array com os resultados de chamar uma função para
cada elemento do array.
Exercício 177: Verificar Existência com includes
Explicação: A função stringToArray usa o método from para converter uma string
em um array de caracteres. O método from cria uma nova instância de Array a partir de
um objeto iterável.
Explicação: A função concatArrays utiliza o método concat para concatenar dois arrays.
O método concat retorna um novo array que é a junção dos arrays fornecidos.
Explicação: A função filterEvens utiliza o método filter para criar um novo array
contendo apenas os números pares do array original. O método filter cria um novo array
com todos os elementos que atendem à função de teste.
Descrição: Dado um array de strings, converta-o em uma única string, onde cada
palavra é separada por um espaço, usando o método join.
Solução com testes:
function joinWords (words) {
return words.join( ' ' );
}
console .log(joinWords([ 'Hello' , 'World' ])); // 'Hello World'
Exercício 186: Dada uma página com uma lista não ordenada
(<ul>) de itens, escreva uma função JavaScript que adicione
um novo item ao final dessa lista.
Descrição:
O objetivo é selecionar uma lista não ordenada e inserir um novo item nessa lista. Para
isso, você usará o document.querySelector para obter a referência da lista e então
adicionar um novo item.
Solução com Testes:
<!-- HTML -->
< ul id= "item-list" >
< li > Item 1 </ li >
< li > Item 2 </ li >
< li > Item 3 </ li >
</ ul >
< button onclick= "addItem()" > Add Item </ button >
< script >
function addItem () {
const ul = document .querySelector( '#item-list' );
const li = document .createElement( 'li' );
li.textContent = `Item ${ul.children.length + 1 }` ;
ul.appendChild(li);
}
</ script >
Explicação:
Nesta solução, temos um botão que, quando clicado, chama a função addItem(). Dentro
desta função:
Selecionamos o elemento <ul> com o id "item-list" usando document.querySelector.
Criamos um novo elemento <li> com document.createElement.
Atribuímos um texto ao elemento <li>, baseado na quantidade atual de itens da lista.
Finalmente, adicionamos este novo <li> ao <ul> usando appendChild.
Exercício 187: Crie uma função que, ao clicar em um botão, altere a cor de
fundo de um parágrafo para azul.
Descrição:
Ao clicar em um botão, você deve selecionar um elemento parágrafo e alterar sua cor de
fundo para azul.
Solução com Testes:
Explicação:
Na solução, ao clicar no botão, a função changeColor() é chamada. Ela seleciona o
parágrafo com id "text" e altera sua propriedade de estilo backgroundColor para 'blue'.
Exercício 188: Crie uma função que exiba em tempo real o que está sendo
digitado em um campo de texto.
Descrição:
Cada vez que um usuário digitar algo em um campo de texto (<input type="text">), o
conteúdo desse campo deve ser exibido em um elemento <p> abaixo dele.
Solução com Testes:
<!-- HTML -->
< input type= "text" id= "user-input" >
< p id= "display-text" ></ p >
< script >
const inputField = document .querySelector( '#user-input' );
const displayText = document .querySelector( '#display-text' );
Explicação:
Usamos o método addEventListener para adicionar um ouvinte ao evento 'input' do
campo de texto. Toda vez que o conteúdo do campo de texto muda, a função é chamada,
atualizando o texto do parágrafo para refletir o valor atual do campo de texto.
Descrição:
Você deve criar um botão que, quando clicado, alternará a classe "ativo" de um elemento
<div>. Se o elemento tiver a classe, ela deve ser removida; se não tiver, deve ser
adicionada.
Solução com Testes:
<!-- HTML -->
< div id= "toggle-element" > Clique no botão para alternar minha classe! </ div
>
< button onclick= "toggleClass()" > Toggle Classe </ button >
< script >
function toggleClass () {
const div = document .querySelector( '#toggle-element' );
div.classList.toggle( 'ativo' );
}
</ script >
Explicação:
Aqui, utilizamos o método classList.toggle do elemento. Esse método verificará se o
elemento tem a classe especificada: se tiver, ele a removerá; se não tiver, ele a
adicionará.
Exercício 190: Dada uma lista de itens, crie uma função que exiba apenas os
itens que contêm uma determinada palavra.
Descrição:
Você terá uma lista não ordenada (<ul>) de itens. Abaixo dela, haverá um campo de
texto e um botão. O usuário pode digitar uma palavra no campo e, ao clicar no botão,
apenas os itens da lista que contêm essa palavra devem ser exibidos.
Solução com Testes:
<!-- HTML -->
< ul id= "item-list" >
< li > Maçã </ li >
< li > Laranja </ li >
< li > Mamão </ li >
< li > Morango </ li >
</ ul >
< input type= "text" id= "filter-input" >
< button onclick= "filterItems()" > Filtrar </ button >
< script >
function filterItems () {
const filter = document .querySelector( '#filter-input'
).value.toLowerCase();
const items = document .querySelectorAll( '#item-list li' );
items.forEach(item => {
if (item.textContent.toLowerCase().includes(filter)) {
item.style.display = '' ;
} else {
item.style.display = 'none' ;
}
});
}
</ script >
Explicação:
Quando o botão é clicado, a função filterItems() é chamada. Essa função primeiro obtém
o valor do campo de texto e o converte para minúsculas. Em seguida, seleciona todos os
itens da lista e verifica se o texto de cada item contém o filtro. Se contiver, o item é
exibido; caso contrário, ele é ocultado.
Exercício 191: Crie uma função que adicione uma classe "visível" a um
elemento quando ele estiver visível na janela de visualização ao rolar a
página.
Descrição:
Você terá um elemento <div> que estará fora da janela de visualização (viewport)
quando a página for carregada. Ao rolar a página e esse elemento entrar na janela de
visualização, adicione a ele a classe "visível".
Solução com Testes:
<!-- HTML -->
< div id= "scroll-element" style= "margin-top: 120vh;" > Sou visível agora? </
div >
< script >
window .addEventListener( 'scroll' , function () {
const div = document .querySelector( '#scroll-element' );
const rect = div.getBoundingClientRect();
if (rect.top <= window .innerHeight && rect.bottom >= 0 ) {
div.classList.add( 'visivel' );
} else {
div.classList.remove( 'visivel' );
}
});
</ script >
Explicação:
Adicionamos um ouvinte de evento para o evento de rolagem (scroll) na janela. Sempre
que o usuário rolar a página, verificamos a posição do elemento usando
getBoundingClientRect(). Se o elemento estiver dentro da janela de visualização,
adicionamos a classe "visível". Caso contrário, removemos a classe.
Exercício 192: Crie um botão que, quando clicado, altere o tema da página
entre claro e escuro.
Descrição:
Haverá um botão na página. Quando clicado, se o tema atual for claro, ele deve mudar
para escuro e vice-versa.
Solução com Testes:
<!-- HTML -->
< button onclick= "toggleTheme()" > Trocar Tema </ button >
< script >
function toggleTheme () {
const body = document .querySelector( 'body' );
if (body.classList.contains( 'dark-theme' )) {
body.classList.remove( 'dark-theme' );
} else {
body.classList.add( 'dark-theme' );
}
}
</ script >
< style >
.dark-theme {
background-color : black;
color : white;
}
</ style >
Explicação:
A função toggleTheme() verifica se o <body> tem a classe dark-theme. Se tiver, ele a
remove, tornando o tema claro; se não, ele adiciona a classe, tornando o tema escuro.
Exercício 193: Crie um botão que, quando clicado, exiba um modal na tela.
O modal deve ter também um botão que o feche.
Descrição:
Haverá um botão na página principal. Quando clicado, um modal (uma pequena
janela/overlay) deve aparecer no centro da tela. Esse modal terá um botão de fechar,
que quando clicado, fechará o modal.
Solução com Testes:
<!-- HTML -->
< button onclick= "showModal()" > Abrir Modal </ button >
< div id= "modal" style= "display: none; position: fixed; top: 50%; left:
50%; transform: translate(-50%, -50%); z-index: 10; background-color: white;
padding: 20px;" >
Isso é um modal!
< button onclick= "closeModal()" > Fechar </ button >
</ div >
< script >
function showModal () {
const modal = document .querySelector( '#modal' );
modal.style.display = 'block' ;
}
function closeModal () {
const modal = document .querySelector( '#modal' );
modal.style.display = 'none' ;
}
</ script >
Explicação:
O modal, por padrão, é ocultado com display: none. Ao clicar no botão para abrir o
modal, a função showModal() é chamada e o modal é exibido alterando o estilo display
para 'block'. O botão fechar no modal chama a função closeModal(), que oculta
novamente o modal.
Exercício 194: Ao clicar em uma imagem na página, mostre essa imagem
em tamanho ampliado em um modal.
Descrição:
Você terá algumas imagens miniaturas na página. Quando o usuário clicar em uma
delas, a imagem deve ser exibida em tamanho maior em um modal. Também deve haver
um botão para fechar o modal.
Solução com Testes:
Explicação:
As imagens miniaturas têm um onclick que chama a função openImage com a URL da
imagem em tamanho completo. Quando clicado, a imagem em tamanho completo é
carregada no modal, que é exibido. O botão de fechar oculta o modal.
Descrição:
O usuário deve ser capaz de fornecer feedback por meio de um formulário que inclui um
campo de texto. Depois de enviar, um alerta de agradecimento deve ser mostrado e o
modal deve ser fechado.
Solução com Testes:
Explicação:
O botão de feedback abre o modal do formulário. Ao enviar o feedback, mostramos um
alerta de agradecimento e fechamos o modal.
Descrição:
Ao lado de um campo de texto, haverá uma contagem regressiva a partir de 150. À
medida que o usuário digita, o contador deve diminuir. Se o usuário exceder 150
caracteres, mostre uma mensagem de erro.
Solução com Testes:
Explicação:
Cada vez que o usuário digita no campo de texto (oninput), chamamos a função
updateCounter(). Esta função atualiza o contador e verifica se o limite de caracteres foi
excedido.
Descrição:
O usuário deve ser capaz de clicar em um botão que alterne o conteúdo de um título e de
um parágrafo simultaneamente.
Solução com Testes:
Explicação:
Inicialmente, capturamos os nossos elementos da DOM, e em seguida, aguardamos o
evento de click do botão e alteramos o conteúdo do título e do parágrafo..
Descrição:
Em vez de usar o dropdown padrão <select>, crie um usando divs e listas. O dropdown
deve exibir as opções quando clicado e permitir ao usuário selecionar uma opção.
Solução com Testes:
<!-- HTML -->
< div class= "dropdown" onclick= "toggleDropdown()" >
< div id= "selected-option" > Opção 1 </ div >
< ul id= "options-list" style= "display: none;" >
< li onclick= "selectOption('Opção 1')" > Opção 1 </ li >
< li onclick= "selectOption('Opção 2')" > Opção 2 </ li >
< li onclick= "selectOption('Opção 3')" > Opção 3 </ li >
</ ul >
</ div >
< script >
function toggleDropdown () {
const list = document .querySelector( '#options-list' );
list.style.display = list.style.display === "none" ? "block" :
"none" ;
}
function selectOption (option) {
const selected = document .querySelector( '#selected-option' );
selected.textContent = option;
toggleDropdown(); // fecha o dropdown após selecionar
}
</ script >
Explicação:
Temos uma div que atua como nosso dropdown. Ao clicar nela, as opções são exibidas.
Ao selecionar uma opção, atualizamos a div para mostrar a opção selecionada e
fechamos o dropdown.
Exercício 199: Implemente uma funcionalidade de arrastar e soltar para
reordenar uma lista.
Descrição:
Você terá uma lista de itens. O usuário deve ser capaz de reordenar essa lista arrastando
e soltando itens.
Solução com Testes:
Explicação:
Usamos os eventos de drag and drop do HTML5. Quando um item é começado a ser
arrastado, armazenamos ele em draggedItem. Quando ele é solto, nós o inserimos antes
do item sobre o qual ele foi solto.
Explicação:
Temos botões que representam abas e divs correspondentes para o conteúdo. Quando
um botão é pressionado, ocultamos todo o conteúdo e exibimos apenas o conteúdo
correspondente ao botão pressionado.
Capítulo 7: Regex
Explicação: A regex verifica se a data tem dois dígitos para o dia (01 a 31), dois dígitos
para o mês (01 a 12) e quatro dígitos para o ano, a segunda parte verifica se a data é
válida, por exemplo: 31/02 passa na regex mas não na última verificação.
Exercício 205: Crie uma expressão regular para validar senhas. As senhas
válidas devem ter pelo menos uma letra maiúscula, uma letra minúscula, um
número e um caracter especial (como !, @, #, $, etc.). Elas devem ter pelo
menos 8 caracteres e no máximo 20.
Descrição: Use uma regex para validar a força de uma senha conforme as condições
fornecidas.
Solução com testes:
function isValidPassword (password) {
const regex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-
z\d@$!%*?&]{8,20}$/ ;
return regex.test(password);
}
// Testes
console .log(isValidPassword( "StrongPass1!" )); // true
console .log(isValidPassword( "weakpass" )); // false
Explicação: A regex usa lookaheads positivos para verificar se a senha contém pelo
menos uma letra minúscula, uma letra maiúscula, um dígito e um caractere especial. Ela
então verifica o comprimento da senha.
Descrição: Dada uma string contendo HTML, remova qualquer parte que seja um
comentário HTML.
Solução com testes:
function removeHtmlComments (text) {
const regex = /<!--[\s\S]*?-->/g ;
return text.replace(regex, '' );
}
// Testes
console .log(removeHtmlComments( "Hello <!-- This is a comment --> World" ));
// "Hello World"
Explicação: A regex captura comentários HTML, que começam com <!-- e terminam
com -->. O método replace é usado para remover esses comentários.
Descrição: Dada uma string HTML, extraia um objeto onde a chave é o nome da tag e
o valor é o conteúdo dentro da tag.
Solução com testes:
Explicação: A regex busca por pares de tags de abertura e fechamento e extrai o nome
da tag e o conteúdo. O resultado é acumulado em um objeto.
Descrição: Dado um texto, determine se ele possui palavras que são repetidas
consecutivamente, independentemente de serem maiúsculas ou minúsculas.
Solução com testes:
function hasConsecutiveRepeats (text) {
const regex = /\b(\w+)\b\s+\b\1\b/i ;
return regex.test(text);
}
// Testes
console .log(hasConsecutiveRepeats( "Hello hello world" )); // true
console .log(hasConsecutiveRepeats( "Hello world" )); // false
Explicação: A regex verifica palavras consecutivas repetidas usando um grupo de
captura e referenciando esse grupo novamente com \1. O modificador i torna a busca
insensível a maiúsculas/minúsculas.