Programação Web · Revisão para Prova

JavaScript
do zero ao real.

Material completo preparado por Felipe Duan (5º Período Ada) para a turma do 3º Período. Cobre toda a ementa com exemplos, analogias e exercícios.

17 Módulos
Exemplos reais
Exercícios práticos
Dicas de prova
Parte 01

O que é JavaScript?

JavaScript (JS) é uma linguagem de programação interpretada, dinâmica e multiparadigma. Foi criada em 1995 por Brendan Eich em apenas 10 dias e rapidamente se tornou a linguagem padrão dos navegadores.

Junto com HTML (estrutura) e CSS (estilo), o JavaScript forma o terceiro pilar do desenvolvimento web front-end — sendo responsável pelo comportamento e interatividade das páginas.

💡
Curiosidade

Apesar do nome, JavaScript não tem relação com a linguagem Java. O nome foi uma jogada de marketing para aproveitar a popularidade do Java na época.

A Tríade da Web

Pense assim — cada tecnologia tem uma responsabilidade clara:

🦴

HTML

Estrutura · O esqueleto da página. Define o que existe.

👗

CSS

Aparência · A roupa. Define como as coisas parecem.

🧠

JavaScript

Comportamento · O cérebro e músculos. Define o que as coisas fazem.

O que dá para fazer com JS?

Como o navegador executa o JavaScript?

Cada navegador tem uma engine JavaScript que interpreta e executa o código:

NavegadorEngine JS
Chrome / EdgeV8
FirefoxSpiderMonkey
SafariJavaScriptCore

O fluxo de leitura de uma página é:

  1. O navegador lê o HTML e monta a árvore de elementos (DOM)
  2. Aplica o CSS e calcula os estilos
  3. Executa o JavaScript que pode modificar tudo isso
Parte 02

Como incluir JS no HTML

Existem três formas de adicionar JavaScript a uma página HTML:

1. Inline (no atributo do elemento)

HTML
<button onclick="alert('Olá!')">Clique aqui</button>
⚠️
Não Recomendado

Mistura lógica com estrutura. Dificulta manutenção e reutilização. Evite sempre.

2. Interno (tag <script> no HTML)

HTML
<script>
  console.log("Olá, mundo!");
</script>

3. Externo (arquivo .js separado) ✅

HTML
<script src="script.js"></script>
💡
Boa Prática

Coloque a tag <script> no final do <body> ou use o atributo defer. Isso garante que o HTML já foi carregado quando o JS executar.

HTML
<!-- Com defer: carrega depois do HTML -->
<script src="script.js" defer></script>

<!-- Estrutura ideal de um arquivo HTML -->
<!DOCTYPE html>
<html>
<head>
  <title>Minha Página</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <!-- conteúdo aqui -->
  <script src="script.js"></script>  <!-- aqui no final ✅ -->
</body>
</html>
Parte 03

Variáveis e Tipos de Dados

Variáveis são espaços na memória onde guardamos informações para usar depois. Em JavaScript moderno, usamos let e const.

Declarando variáveis

JS
// let → valor pode mudar (variável)
let nome = "Maria";
let idade = 22;
nome = "João";         // ✅ OK, pode reatribuir

// const → valor constante (não pode ser reatribuído)
const PI = 3.14159;
PI = 3;              // ❌ Erro! Não pode reatribuir

// var → evitar (escopo problemático, legado)
var antigo = "não use";
ℹ️
Regra Geral

Use const por padrão. Só mude para let se precisar reatribuir o valor. Nunca use var em código novo.

Tipos Primitivos

TipoExemploDescrição
string"Olá", 'mundo', `template`Texto
number42, 3.14Números inteiros e decimais
booleantrue, falseVerdadeiro ou falso
undefinedundefinedVariável declarada sem valor
nullnullAusência intencional de valor

Verificando tipos com typeof

JS
console.log(typeof "Olá");       // "string"
console.log(typeof 42);         // "number"
console.log(typeof true);       // "boolean"
console.log(typeof undefined);  // "undefined"
console.log(typeof null);       // "object" ← bug histórico do JS!

Template Literals (template strings)

Usam crase (`) e permitem interpolação com ${}:

JS
const nome = "Ana";
const idade = 25;

// Concatenação clássica (evitar)
console.log("Meu nome é " + nome + " e tenho " + idade + " anos.");

// Template literal ✅
console.log(`Meu nome é ${nome} e tenho ${idade} anos.`);
Parte 04

Operadores

Aritméticos

JS
let a = 10, b = 3;

console.log(a + b);  // 13  (soma)
console.log(a - b);  // 7   (subtração)
console.log(a * b);  // 30  (multiplicação)
console.log(a / b);  // 3.33 (divisão)
console.log(a % b);  // 1   (módulo / resto)
console.log(a ** b); // 1000 (exponenciação)

Comparação — ⚠️ Cai muito na prova!

⚠️
Atenção

Sempre prefira === e !== (comparação estrita). O == faz conversão automática de tipo e gera comportamentos inesperados.

JS
console.log(5 == "5");   // true  (compara só valor — CUIDADO!)
console.log(5 === "5");  // false (compara valor E tipo) ✅

console.log(5 != "5");   // false
console.log(5 !== "5");  // true  ✅

console.log(10 > 5);     // true
console.log(10 <= 10);   // true

Lógicos

JS
console.log(true && false);  // false (E — ambos precisam ser true)
console.log(true || false);  // true  (OU — basta um ser true)
console.log(!true);          // false (NÃO — inverte)

Incremento e Atribuição

JS
let x = 5;
x++;        // x = 6 (incrementa 1)
x--;        // x = 5 (decrementa 1)
x += 10;   // x = 15 (x = x + 10)
x *= 2;    // x = 30 (x = x * 2)
x -= 5;    // x = 25
Parte 05

Estruturas Condicionais

if / else if / else

JS
const nota = 7.5;

if (nota >= 7) {
  console.log("Aprovado! 🎉");
} else if (nota >= 5) {
  console.log("Recuperação 📋");
} else {
  console.log("Reprovado 😔");
}

Operador Ternário

Uma forma curta de escrever um if/else simples:

JS
const idade = 18;
// condição ? valorSeTrue : valorSeFalse
const status = idade >= 18 ? "Maior de idade" : "Menor de idade";
console.log(status); // "Maior de idade"

switch

Use quando você precisa comparar uma variável com muitos valores possíveis:

JS
const diaSemana = 3;

switch (diaSemana) {
  case 1: console.log("Domingo");   break;
  case 2: console.log("Segunda");   break;
  case 3: console.log("Terça");     break;
  case 4: console.log("Quarta");    break;
  case 5: console.log("Quinta");    break;
  case 6: console.log("Sexta");     break;
  case 7: console.log("Sábado");    break;
  default: console.log("Dia inválido");
}
💡
Dica

Não esqueça o break em cada case do switch! Sem ele, o código continua executando os cases seguintes (comportamento chamado "fall-through").

Parte 06

Estruturas de Repetição

Loops permitem executar um bloco de código várias vezes. O computador ama repetição — e é onde ele brilha.

for

JS
// estrutura: for (inicialização; condição; incremento)
for (let i = 1; i <= 5; i++) {
  console.log(`Número: ${i}`);
}
// Saída: Número: 1, Número: 2, ..., Número: 5

while

JS
let contador = 1;

while (contador <= 5) {
  console.log(`Contagem: ${contador}`);
  contador++;
}

for...of (percorrer arrays)

JS
const frutas = ["Maçã", "Banana", "Uva"];

for (const fruta of frutas) {
  console.log(fruta);
}
// Saída: Maçã, Banana, Uva
💡
Dica

Use for...of para iterar valores de arrays. Para acessar índice e valor ao mesmo tempo, use o for clássico ou .forEach().

Parte 07

Funções

Funções encapsulam blocos de código reutilizáveis. São fundamentais para organizar e evitar repetição.

Declaração clássica

JS
function saudacao(nome) {
  return `Olá, ${nome}!`;
}

console.log(saudacao("Carlos")); // "Olá, Carlos!"

O comando return

⚠️
Ponto crítico

Existe diferença entre mostrar (console.log) e retornar (return) um valor. Uma função que usa return devolve um valor que pode ser guardado ou usado. console.log apenas exibe, não retorna nada útil.

❌ Sem return
function soma(a, b) {
  console.log(a + b); // só exibe
}

let result = soma(3, 4);
console.log(result); // undefined!
✅ Com return
function soma(a, b) {
  return a + b; // retorna
}

let result = soma(3, 4);
console.log(result); // 7 ✅

Arrow Functions (ES6+)

JS
// Sintaxe completa
const somar = (a, b) => {
  return a + b;
};

// Sintaxe curta (retorno implícito)
const somar = (a, b) => a + b;

console.log(somar(3, 7)); // 10

Parâmetros padrão

JS
function potencia(base, expoente = 2) {  // expoente padrão = 2
  return base ** expoente;
}

console.log(potencia(5));     // 25  (expoente = 2)
console.log(potencia(5, 3));  // 125 (expoente = 3)
ℹ️
Quando usar Arrow Functions?

Arrow functions são ideais para funções curtas e callbacks. Para métodos de objetos ou funções que precisam do this próprio, prefira a declaração clássica.

Parte 08

Arrays

Arrays são listas ordenadas de valores. Podem guardar qualquer tipo de dado e são indexados a partir do zero.

JS
const frutas = ["Maçã", "Banana", "Uva"];

console.log(frutas[0]);  // "Maçã"   (índice 0)
console.log(frutas[1]);  // "Banana" (índice 1)
console.log(frutas.length); // 3 (tamanho)

Métodos essenciais

JS
const nums = [1, 2, 3];

nums.push(4);       // [1, 2, 3, 4] → adiciona no fim
nums.pop();        // [1, 2, 3]    → remove do fim
nums.unshift(0);  // [0, 1, 2, 3] → adiciona no início
nums.shift();      // [1, 2, 3]    → remove do início

// Verificar se inclui algo
nums.includes(2);  // true

// Juntar elementos em string
nums.join(" - ");   // "1 - 2 - 3"

Métodos modernos (muito cobrados!)

JS
const nums = [1, 2, 3, 4, 5];

// forEach — executa algo para cada item (não retorna)
nums.forEach(n => console.log(n));

// map — cria um novo array transformando cada item
const dobrados = nums.map(n => n * 2);
console.log(dobrados); // [2, 4, 6, 8, 10]

// filter — filtra itens que satisfazem uma condição
const pares = nums.filter(n => n % 2 === 0);
console.log(pares);    // [2, 4]

// find — encontra o primeiro item que satisfaz a condição
const achou = nums.find(n => n > 3);
console.log(achou);    // 4

// reduce — reduz o array a um único valor
const soma = nums.reduce((acc, n) => acc + n, 0);
console.log(soma);     // 15
Parte 09

Objetos

Objetos modelam entidades do mundo real usando pares de chave: valor. Pense em um objeto como uma ficha com propriedades.

JS
const aluno = {
  nome: "Felipe",
  idade: 20,
  curso: "Engenharia de Software",
  ativo: true
};

// Acessar propriedades
console.log(aluno.nome);       // "Felipe" (dot notation)
console.log(aluno["idade"]);  // 20       (bracket notation)

// Alterar propriedade
aluno.idade = 21;

// Adicionar nova propriedade
aluno.email = "felipe@email.com";

Objetos com métodos

JS
const pessoa = {
  nome: "Ana",
  idade: 25,
  saudacao() {
    return `Olá, sou ${this.nome}!`;
  }
};

console.log(pessoa.saudacao()); // "Olá, sou Ana!"

Desestruturação (muito usado)

JS
const aluno = { nome: "João", curso: "Engenharia de Software", nota: 8.5 };

// Extrai propriedades direto em variáveis
const { nome, nota } = aluno;
console.log(nome);  // "João"
console.log(nota);  // 8.5
Parte 10

DOM — Manipulação da Página

🏆 Este é o módulo mais importante para desenvolvimento web. É aqui que o JavaScript ganha superpoderes.

DOM (Document Object Model) é a representação da página HTML como uma árvore de objetos que o JavaScript pode ler e modificar em tempo real.

JS
// O objeto 'document' representa a página inteira
console.log(document);           // a página HTML
console.log(document.title);     // título da aba
console.log(document.body);      // body da página

Selecionando elementos

JS
// Por ID (único) — mais rápido
const titulo = document.getElementById("meu-titulo");

// Por seletor CSS — mais flexível ✅
const botao  = document.querySelector(".btn-enviar");     // primeiro match
const itens  = document.querySelectorAll("li");            // todos os matches

// Seletores CSS funcionam igual: #id, .classe, tag, [atributo]
const input  = document.querySelector("input[type='email']");

Manipulando conteúdo

JS
const el = document.querySelector("#mensagem");

// Ler e alterar texto puro (mais seguro)
console.log(el.innerText);
el.innerText = "Novo texto!";

// Ler e alterar HTML interno
el.innerHTML = "<strong>Texto em negrito</strong>";

Manipulando estilos e classes

JS
const caixa = document.querySelector(".caixa");

// Estilo direto (evitar para muitas mudanças)
caixa.style.color = "red";
caixa.style.fontSize = "20px";

// Classes (preferível) ✅
caixa.classList.add("ativo");       // adiciona classe
caixa.classList.remove("ativo");    // remove classe
caixa.classList.toggle("escuro");   // adiciona/remove (toggle)
caixa.classList.contains("ativo"); // true/false

Criando e inserindo elementos

JS
// Criar um novo elemento
const novoItem = document.createElement("li");
novoItem.innerText = "Nova tarefa";
novoItem.classList.add("item-lista");

// Inserir no DOM
const lista = document.querySelector("#lista");
lista.appendChild(novoItem);    // no final

// Remover elemento
novoItem.remove();

Lendo valores de inputs

JS
const campo = document.querySelector("#nome");

// Ler valor digitado
const valorDigitado = campo.value;

// Limpar o campo
campo.value = "";
Parte 11

Eventos

Eventos são ações do usuário ou do navegador que o JavaScript pode "escutar" e responder. É o que torna as páginas verdadeiramente interativas.

addEventListener — a forma correta

JS
const botao = document.querySelector("#btn");

// elemento.addEventListener("evento", função)
botao.addEventListener("click", function() {
  console.log("Botão clicado!");
});

// Com arrow function (mais moderno)
botao.addEventListener("click", () => {
  console.log("Clicado!");
});

Eventos mais importantes

EventoQuando ocorreUso comum
clickClique do mouseBotões, links
inputDigitação em campoBusca em tempo real
submitEnvio de formulárioValidação
keydownTecla pressionadaAtalhos, Enter
mouseoverMouse sobre elementoTooltips, hover
mouseoutMouse sai do elementoReset de hover
changeMudança em select/checkboxFiltros
DOMContentLoadedHTML carregadoInicialização

O objeto event

JS
botao.addEventListener("click", (event) => {
  console.log(event.target);      // elemento que disparou
  console.log(event.type);        // tipo do evento ("click")
});

// Detectar qual tecla foi pressionada
document.addEventListener("keydown", (e) => {
  console.log(e.key);             // "Enter", "a", "Escape", etc.
  if (e.key === "Enter") {
    console.log("Enter pressionado!");
  }
});
Parte 12

Formulários

Formulários são a principal forma de capturar dados do usuário. JavaScript permite validar, interceptar e processar esses dados antes de qualquer envio.

preventDefault — essencial!

⚠️
Muito importante

event.preventDefault() impede o comportamento padrão do formulário (recarregar a página ao enviar). Sem isso, a página recarrega e você perde os dados processados.

JS
const formulario = document.querySelector("#meu-form");

formulario.addEventListener("submit", (event) => {
  event.preventDefault(); // ← SEMPRE coloque isso primeiro!

  const nome  = document.querySelector("#nome").value;
  const email = document.querySelector("#email").value;

  // Validação
  if (nome === "") {
    alert("Por favor, preencha o nome!");
    return; // para a execução
  }

  console.log(`Enviando para: ${email}`);
});

Exemplo completo: formulário com validação

HTML + JS
<!-- HTML -->
<form id="form-cadastro">
  <input type="text" id="nome" placeholder="Seu nome">
  <input type="email" id="email" placeholder="Seu email">
  <button type="submit">Enviar</button>
  <p id="mensagem"></p>
</form>

// JavaScript
const form = document.querySelector("#form-cadastro");
const msg  = document.querySelector("#mensagem");

form.addEventListener("submit", (e) => {
  e.preventDefault();

  const nome  = document.querySelector("#nome").value.trim();
  const email = document.querySelector("#email").value.trim();

  if (!nome || !email) {
    msg.innerText = "❌ Preencha todos os campos!";
    return;
  }

  msg.innerText = `✅ Bem-vindo, ${nome}! Email: ${email}`;
  form.reset(); // limpa o formulário
});
Parte 13

Recursos Modernos do JS

Spread Operator (...)

JS
const a = [1, 2, 3];
const b = [4, 5];
const uniao = [...a, ...b];  // [1, 2, 3, 4, 5]

// Clonar objetos
const original = { nome: "Ana" };
const copia = { ...original, idade: 25 };
// { nome: "Ana", idade: 25 }

Métodos de String

JS
const texto = "  Olá, Mundo!  ";

texto.toUpperCase();   // "  OLÁ, MUNDO!  "
texto.toLowerCase();   // "  olá, mundo!  "
texto.trim();          // "Olá, Mundo!"   (remove espaços das bordas)
texto.includes("Mundo"); // true
texto.split(",");      // ["  Olá", " Mundo!  "]
texto.replace("Olá", "Oi"); // "  Oi, Mundo!  "
texto.startsWith("  Olá");  // true

Nullish Coalescing (??)

JS
// Usa valor padrão quando a variável for null ou undefined
const nome = null;
const exibir = nome ?? "Anônimo";
console.log(exibir); // "Anônimo"

Optional Chaining (?.)

JS
const usuario = { perfil: { avatar: "foto.jpg" } };

// Sem ?. — pode dar erro se perfil for undefined
console.log(usuario.endereco.rua);  // ❌ TypeError

// Com ?. — retorna undefined sem quebrar
console.log(usuario?.endereco?.rua); // undefined (sem erro) ✅
Parte 14

JavaScript moderno: ES6+, Promises, async/await e módulos

A partir do ES6 (ES2015) o JavaScript ganhou sintaxe e recursos que hoje são o padrão em tutoriais, ferramentas e APIs do navegador. Esta parte organiza o que mais aparece no dia a dia — inclusive por baixo do fetch, que você verá na Parte 15.

📚
Onde encaixa

Você já viu arrow functions, template literals e trechos de ES6+ nas partes anteriores (e recursos como spread e optional chaining na Parte 13). Aqui o foco é: desestruturação, rest/parâmetros padrão, o modelo mental de Promise, .then() vs async/await e import/export.

Desestruturação — extrair valores de objetos e arrays

Em vez de acessar campo por campo, você “abre” a estrutura na declaração.

JS
// Objeto — nomes devem bater com as chaves
const turma = { id: 1, nome: "ADA", periodo: 5 };
const { nome, periodo } = turma;
console.log(nome, periodo); // "ADA" 5

// Renomear na hora
const { nome: titulo } = turma;

// Array — posição importa
const coords = [10, 20];
const [x, y] = coords;

Parâmetros padrão e rest (...)

JS
// Valor padrão se o argumento vier undefined
function saudar(nome = "visitante") {
  return `Olá, ${nome}!`;
}

// Rest — agrupa o "resto" dos argumentos em um array
function soma(...numeros) {
  return numeros.reduce((acc, n) => acc + n, 0);
}
soma(1, 2, 3); // 6

O spread de arrays/objetos (clonar, juntar) você revisa na Parte 13 — é o mesmo ..., em outro contexto.

Promise — “um valor que ainda vai chegar”

Operações assíncronas (rede, timers, leitura de arquivo no Node…) não bloqueiam a fila principal. O navegador modela muitas delas com Promises: um objeto que representa eventualmente sucesso (fulfilled) ou falha (rejected).

JS
const promessa = new Promise((resolve, reject) => {
  // função executora — chamada resolve(valor) ou reject(erro)
  setTimeout(() => resolve(42), 500);
});

promessa
  .then(valor => console.log(valor))   // 42
  .catch(err => console.error(err))
  .finally(() => console.log("fim"));

Encadeamento com .then()

Cada .then pode devolver um valor ou outra Promise; o próximo elo espera esse resultado. Assim você evita “callback hell” em estilo antigo — mas muitos .then seguidos ainda podem ficar difíceis de ler.

JS
fetch("https://api.exemplo.com/dados")
  .then(res => {
    if (!res.ok) throw new Error("HTTP " + res.status);
    return res.json(); // devolve Promise → próximo .then recebe o objeto
  })
  .then(dados => console.log(dados))
  .catch(err => console.error(err));

async / await — mesma Promise, outra leitura

async function sempre retorna uma Promise. Dentro dela, await pausa só essa função até a Promise resolver — o código parece síncrono, linha a linha.

JS
async function carregar() {
  const res = await fetch("https://api.exemplo.com/dados");
  if (!res.ok) throw new Error("HTTP " + res.status);
  const dados = await res.json();
  console.log(dados);
}
💡
.then() vs async/await — quando usar?

Mesma máquina: await é só açúcar sobre Promises. Equipes modernas costumam preferir async/await para fluxos longos e try/catch. .then() continua válido em encadeamentos curtos ou quando você não quer marcar a função inteira como async. Em provas, entender os dois conta mais que escolher um estilo.

Aspecto.then()async / await
Erros.catch() no encadeamentotry { ... } catch { ... }
Último valorCada return passa ao próximo thenreturn normal dentro da função async
Funções paralelasPromise.all([...])await Promise.all([...])
JS
// Duas requisições em paralelo — espera as duas terminarem
async function carregarDois() {
  const [a, b] = await Promise.all([
    fetch("/api/a").then(r => r.json()),
    fetch("/api/b").then(r => r.json()),
  ]);
  console.log(a, b);
}

Módulos ES — import e export

Em projetos reais (e em trabalhos que pedem script.js separado), você divide código em arquivos. O padrão oficial no navegador é ES Module: cada arquivo é um módulo com escopo próprio.

JS — helpers.js
// export nomeado — vários por arquivo
export function formatarData(iso) { /* ... */ }
export const API_BASE = "https://api.exemplo.com";

// export default — no máximo um por arquivo (o “principal”)
export default function criarCard(item) { /* ... */ }
JS — app.js
import criarCard from "./helpers.js";           // default
import { formatarData, API_BASE } from "./helpers.js"; // nomeados
import { formatarData as fmt } from "./helpers.js";   // alias
HTML
<!-- O navegador baixa módulos com defer implícito — ordem importa pelos imports -->
<script type="module" src="./app.js"></script>
⚠️
caminhos e protocolo

import usa caminhos relativos (./) na maioria dos projetos. Abrir HTML pelo protocolo file:// pode bloquear módulos por política do navegador — use um servidor local simples (ex.: extensão Live Server, ou python -m http.server) ao testar type="module".

import() dinâmico (carregar sob demanda)

A forma estática acima é analisada em tempo de build/carregamento. Às vezes você só quer carregar um módulo depois de um evento — aí existe import('./modulo.js'), que devolve uma Promise.

JS
botao.addEventListener("click", async () => {
  const { graficosExtras } = await import("./graficos.js");
  graficosExtras();
});
🎯
Próximo passo

Fetch devolve uma Promise de Response; por isso combina naturalmente com .then ou await. Na Parte 15 você aplica isso a APIs REST e JSON.

Parte 15

HTTP no navegador, Fetch API e JSON

O método fetch retorna uma Promise de Response — combinar com .then() ou await é o mesmo modelo da Parte 14. Quando uma página precisa buscar ou enviar dados para um servidor (por exemplo uma API REST), o navegador faz uma requisição HTTP. Em código moderno isso costuma ser feito com fetch e dados em formato JSON.

🔗
Conexão com o que você já viu

Você já usa DOM, eventos e formulários. O fluxo típico: usuário envia um formulário → você monta um objeto JavaScript → JSON.stringify no corpo do POST → await fetch(...) (ou .then) → atualiza a tela com innerHTML/createElement usando a resposta, sem recarregar a página.

Request e response — visão rápida

StatusSignificado comumO que fazer na UI
200 / 201SucessoMostrar confirmação; atualizar lista/dados na tela
400 / 422Dados inválidosLer mensagem da API (se houver) e exibir ao usuário
404Recurso não existeAvisar que não foi encontrado
500+Falha no servidorMensagem genérica “tente novamente”; não culpar o usuário

JSON — formato texto dos dados

Na linguagem JS você trabalha com objetos e arrays. Na rede os dados viram string JSON. Duas funções fazem a ponte:

JS
const objeto = { nome: "ADA", periodo: 5 };

// Objeto → string JSON (para enviar no body)
const texto = JSON.stringify(objeto);
// '{"nome":"ADA","periodo":5}'

// String JSON → objeto (para ler response)
const deVolta = JSON.parse(texto);

GET com fetch — buscar dados

Por padrão fetch(url) já usa método GET. A resposta não é o JSON pronto: primeiro você obtém o objeto Response, depois chama .json() (assíncrono).

JS
async function carregarTurmas() {
  const url = "https://api.exemplo.com/turmas";
  const resposta = await fetch(url);

  if (!resposta.ok) {
    console.error("Erro HTTP", resposta.status);
    return;
  }

  const lista = await resposta.json();
  console.log(lista); // array ou objeto — depende da API
}

POST com JSON — criar recurso

Envie o cabeçalho Content-Type: application/json e o corpo como string JSON.

JS
async function criarTurma(nome, periodo, ano) {
  const resposta = await fetch("https://api.exemplo.com/turmas", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ nome, periodo, ano }),
  });

  if (!resposta.ok) {
    // opcional: const erro = await resposta.json();
    throw new Error("Falha ao criar");
  }

  return await resposta.json();
}

Validação antes do fetch

O servidor também valida — mas você deve validar no JS antes de chamar a API: campos vazios, formato de email, número em intervalo válido, etc. Use os mesmos padrões da Parte 12 (preventDefault, trim, mensagens em um elemento na página).

try/catch — rede e exceções

fetch só “quebra” com catch em erros de rede (offline, DNS, CORS bloqueado conforme o caso). Um HTTP 404 ou 422 não lança exceção por si só — por isso sempre combine com response.ok ou response.status.

JS
try {
  const res = await fetch(url);
  if (!res.ok) {
    mostrarErro(`Servidor respondeu ${res.status}`);
    return;
  }
  const dados = await res.json();
  mostrarSucesso(dados);
} catch (e) {
  mostrarErro("Sem conexão ou URL inválida.");
}
⚠️
CORS — navegador vs Postman

Browsers aplicam a política CORS: o servidor precisa autorizar o seu domínio nas respostas. No Postman ou curl isso não aparece — lá funciona e no site pode falhar. Se a API da disciplina já permite seu front, ótimo; se não, só o professor/servidor pode ajustar.

💡
Checklist para trabalhos com API

1) GET ao carregar para listar. 2) POST em submit com preventDefault. 3) Atualizar o DOM após sucesso (sem location.reload()). 4) Mensagens claras para sucesso e para cada faixa de erro HTTP. 5) Separar HTML / CSS / JS em arquivos se o enunciado pedir.

Parte 16

Erros Comuns e Debug

Erros mais frequentes

ErroCausaSolução
ReferenceError Variável não existe Verificar nome e escopo
TypeError Tipo errado (null, undefined) Verificar se elemento existe no DOM
SyntaxError Erro de sintaxe no código Procurar colchete/chave faltando
Cannot read property of null Elemento não encontrado no DOM Verificar seletor CSS ou posição do script

Ferramentas de debug

JS
// console.log — sua principal ferramenta
console.log("Verificando valor:", variavel);

// console.error — destaca erros em vermelho
console.error("Algo deu errado!");

// console.table — exibe arrays/objetos como tabela
console.table(meuArray);

// typeof — para entender o tipo de uma variável
console.log(typeof minhaVariavel);

// Verificar se elemento existe antes de usar
const el = document.querySelector("#meu-id");
if (el) {
  el.innerText = "Seguro!"; // só executa se encontrar
}
💡
DevTools — F12 é seu melhor amigo

Pressione F12 no navegador para abrir o DevTools. A aba Console mostra erros e logs. A aba Elements mostra o DOM em tempo real. A aba Sources permite debugar linha a linha.

Aba Network — requisições HTTP

A aba Network lista cada requisição feita pela página: método (GET/POST), URL, status HTTP, tempo e tamanho da resposta. Ao trabalhar com fetch, selecione a linha correspondente e confira Headers e Response — você vê o JSON bruto que a API devolveu (ou o corpo de erro). Sem isso, adivinhar por que a lista não atualiza vira perda de tempo.

Parte 17

Exercícios Práticos

Nível 1 — Fundamentos

  1. Declare variáveis com seu nome, idade e curso usando const e let. Exiba uma apresentação com template literal.
  2. Crie uma função que recebe uma nota e retorna "Aprovado", "Recuperação" ou "Reprovado".
  3. Faça um loop que exibe a tabuada do 7 completa no console.
  4. Crie um array com 5 frutas e exiba cada uma usando for...of.
  5. Crie um objeto representando um produto com nome, preço e estoque.

Nível 2 — DOM e Eventos

  1. Crie um botão que, ao ser clicado, muda o texto de um parágrafo.
  2. Faça um contador com botões de + e − que exibe o valor na tela.
  3. Implemente um botão de dark/light mode que troca a classe do body.
  4. Crie um campo de busca que filtra itens de uma lista conforme o usuário digita.
  5. Faça um botão "mostrar/esconder senha" em um campo de senha.

Nível 3 — Projetos

  1. To-do List: Adicione tarefas, marque como concluídas e remova.
  2. Calculadora: Interface com botões numéricos e operações básicas.
  3. Formulário com validação: Nome, email e senha com feedback visual.
  4. Quiz: 5 perguntas de múltipla escolha com pontuação final.

Nível 4 — JS moderno e API (integração)

  1. Crie helpers.js com um export nomeado (ex.: função que formata texto) e um export default; em app.js, importe os dois com import e use no DOM. Suba com servidor local e <script type="module">.
  2. Escreva a mesma função que carrega dados usando só .then()/.catch(); depois reescreva com async/await + try/catch. Compare a legibilidade.
  3. Consuma uma API pública (ex.: JSONPlaceholder) com fetch: primeiro encadeando .then, depois em uma versão async. Liste itens no DOM e trate !response.ok.
  4. Monte um POST com corpo JSON; valide campos no JS antes de enviar e exiba mensagens diferentes para sucesso e para erro HTTP (400/422/404).
  5. No DevTools → Network, compare uma chamada feita com encadeamento .then e outra com await — método, status e corpo devem ser iguais; só muda o estilo do código.
🎯
Dica de prova

Caia sempre em: == vs ===, DOM, eventos com addEventListener, return, let / const / var. Em código atual: Promises, async/await ou .then(), e organização com módulos. Para trabalhos com servidor: fetch, JSON, validação de formulário e status HTTP na interface (layout responsivo é CSS da disciplina — use Flexbox/Grid nas folhas de estilo).