📦 JavaScript — Módulos 01–06

Aprende JavaScript
do zero ao avançado

Seis módulos progressivos com teoria clara, exemplos reais e exercícios práticos. Em português europeu.

▶ Começar pelo Módulo 01 ← Índice do Curso
Progresso JS:
📦
JavaScript · 01
Variáveis e Tipos de Dados
var, let, const — diferenças e boas práticas. Strings, números, booleanos, null e undefined.
📖 6 lições
✏️ 4 exercícios
1.1 var, let e const — qual usar? ▾

Em JavaScript existem três formas de declarar variáveis: var, let e const. Hoje em dia, var é considerada obsoleta — tem comportamento imprevisível ligado ao hoisting e não respeita blocos.

exemplo.js
// ❌ Evitar — escopo de função, hoisting estranho
var nome = "Ana";

// ✅ Usar — reatribuível, escopo de bloco
let contador = 0;
contador = 1; // OK

// ✅ Preferir sempre que possível — imutável (referência)
const PI = 3.14159;
// PI = 3; → TypeError!
Usa sempre const por defeito. Só usa let quando precisas de reatribuir o valor. Nunca uses var.
1.2 Tipos primitivos: string, number, boolean ▾

JavaScript tem 7 tipos primitivos. Os mais usados são string, number e boolean.

const nome = "João";        // string
const idade = 28;           // number
const ativo = true;         // boolean
const preco = 9.99;         // number (decimais também)
const vazio = null;         // null
let indefinido;              // undefined

// Verificar tipo:
typeof nome;    // "string"
typeof idade;   // "number"
typeof ativo;   // "boolean"
1.3 Strings — métodos essenciais ▾

Strings têm dezenas de métodos úteis. Aqui estão os que vais usar mais frequentemente.

const frase = "Olá, Mundo!";

frase.length;               // 11
frase.toUpperCase();         // "OLÁ, MUNDO!"
frase.toLowerCase();         // "olá, mundo!"
frase.includes("Mundo");    // true
frase.startsWith("Olá");   // true
frase.replace("Mundo", "JS"); // "Olá, JS!"
frase.split(", ");          // ["Olá", "Mundo!"]
frase.trim();                // remove espaços no início/fim
frase.slice(4, 9);          // "Mundo"

// Template literals (backticks)
const msg = `Olá, ${frase}! Tens ${28} anos.`;
1.4 Números e operações matemáticas ▾

JavaScript tem apenas um tipo numérico: number. Inclui inteiros e decimais (vírgula flutuante).

// Operadores básicos
10 + 3;   // 13
10 - 3;   // 7
10 * 3;   // 30
10 / 3;   // 3.333...
10 % 3;   // 1 (resto da divisão)
2 ** 8;   // 256 (potência)

// Math — objeto com funções matemáticas
Math.round(4.6);    // 5
Math.floor(4.9);    // 4
Math.ceil(4.1);     // 5
Math.abs(-7);       // 7
Math.max(3, 7, 2);  // 7
Math.random();      // 0.0 a 0.999...

// Cuidado com decimais!
(0.1 + 0.2).toFixed(1); // "0.3" (string!)
1.5 Condicionais: if, else, switch, ternário ▾

Condicionais permitem que o código tome decisões com base em valores.

const nota = 14;

// if / else if / else
if (nota >= 18) {
  console.log("Muito Bom");
} else if (nota >= 14) {
  console.log("Bom");
} else if (nota >= 10) {
  console.log("Suficiente");
} else {
  console.log("Negativo");
}

// Operador ternário — condição ? seVerdade : seFalso
const resultado = nota >= 10 ? "Passou" : "Reprovou";

// Operadores de comparação
5 === 5;   // true (igualdade estrita — sempre usar!)
5 !== 3;   // true
5 == "5";  // true (evitar — faz coerção de tipos)
Usa sempre === (três iguais) em vez de ==. O operador == faz conversão de tipos automática que pode causar bugs inesperados.
1.6 Loops: for, while, for...of ▾

Loops permitem repetir blocos de código. Cada tipo tem o seu caso de uso ideal.

// for clássico — quando sabes quantas iterações
for (let i = 0; i < 5; i++) {
  console.log(i); // 0, 1, 2, 3, 4
}

// while — enquanto condição for verdade
let x = 10;
while (x > 0) {
  console.log(x);
  x -= 2;
}

// for...of — percorrer arrays (mais limpo)
const frutas = ["maçã", "banana", "laranja"];
for (const fruta of frutas) {
  console.log(fruta);
}

// for...in — percorrer propriedades de objetos
const pessoa = { nome: "Ana", idade: 30 };
for (const chave in pessoa) {
  console.log(chave, pessoa[chave]);
}
Exercícios do Módulo 01
Fácil
Conversor de Temperatura
Escreve uma função celsiusParaFahrenheit(c) que converte graus Celsius para Fahrenheit. Fórmula: F = C × 9/5 + 32
function celsiusParaFahrenheit(c) {
  // O teu código aqui
}

console.log(celsiusParaFahrenheit(0));   // 32
console.log(celsiusParaFahrenheit(100)); // 212
function celsiusParaFahrenheit(c) {
  return c * 9 / 5 + 32;
}
Fácil
Classificar Nota
Escreve uma função classificarNota(n) que retorna "Muito Bom" (≥18), "Bom" (≥14), "Suficiente" (≥10) ou "Negativo" (<10).
function classificarNota(n) {
  // O teu código aqui
}

console.log(classificarNota(19)); // "Muito Bom"
console.log(classificarNota(15)); // "Bom"
console.log(classificarNota(8));  // "Negativo"
function classificarNota(n) {
  if (n >= 18) return "Muito Bom";
  if (n >= 14) return "Bom";
  if (n >= 10) return "Suficiente";
  return "Negativo";
}
Médio
Tabuada
Cria uma função tabuada(n) que usa um loop para imprimir a tabuada do número n de 1 a 10.
function tabuada(n) {
  // Usa um loop for
}

tabuada(7);
// 7 × 1 = 7
// 7 × 2 = 14
// ...
function tabuada(n) {
  for (let i = 1; i <= 10; i++) {
    console.log(`${n} × ${i} = ${n * i}`);
  }
}
Próximo módulo
🔧 Funções e Arrow Functions
→
🔧
JavaScript · 02
Funções e Arrow Functions
Declaração, expressão e arrow functions. Parâmetros, retorno e funções de primeira classe.
📖 8 lições
✏️ 6 exercícios
2.1 Declaração vs Expressão de Função ▾

Existem duas formas principais de criar funções em JavaScript, com uma diferença importante: o hoisting.

// Declaração — sofre hoisting (pode chamar antes de declarar)
somar(2, 3); // funciona!
function somar(a, b) {
  return a + b;
}

// Expressão — NÃO sofre hoisting
const multiplicar = function(a, b) {
  return a * b;
};

// Arrow function (ES6+) — forma mais concisa
const dividir = (a, b) => a / b;

// Arrow com corpo de bloco
const potencia = (base, exp) => {
  const resultado = base ** exp;
  return resultado;
};
2.2 Parâmetros e valores por defeito ▾

Funções podem ter valores por defeito para os parâmetros — muito útil para tornar argumentos opcionais.

// Sem valor por defeito — undefined se não for passado
function saudar(nome) {
  console.log(`Olá, ${nome}!`);
}
saudar(); // "Olá, undefined!"

// Com valor por defeito (ES6+)
function saudar(nome = "visitante") {
  console.log(`Olá, ${nome}!`);
}
saudar();          // "Olá, visitante!"
saudar("Ana");   // "Olá, Ana!"

// Rest params — número variável de argumentos
const somarTodos = (...nums) => nums.reduce((acc, n) => acc + n, 0);
somarTodos(1, 2, 3, 4); // 10
2.3 Funções de primeira classe e callbacks ▾

Em JavaScript, funções são cidadãs de primeira classe — podem ser guardadas em variáveis, passadas como argumento e retornadas de outras funções.

// Função como argumento (callback)
function executar(fn, valor) {
  return fn(valor);
}

const dobro = n => n * 2;
executar(dobro, 5); // 10

// setTimeout usa callback
setTimeout(() => {
  console.log("Passou 2 segundos!");
}, 2000);

// Função que retorna função (higher-order function)
function multiplicadorDe(n) {
  return x => x * n;
}
const triplicar = multiplicadorDe(3);
triplicar(7); // 21
2.4 Escopo e closures ▾

O escopo define onde uma variável é acessível. Um closure ocorre quando uma função interna lembra o escopo da função externa, mesmo após esta ter terminado.

// Escopo de bloco com let/const
{
  let x = 10;
  console.log(x); // 10
}
// console.log(x); → ReferenceError!

// Closure — a função "lembra" variáveis do contexto pai
function criarContador() {
  let count = 0;
  return () => {
    count++;
    return count;
  };
}

const contador = criarContador();
contador(); // 1
contador(); // 2
contador(); // 3
Closures são fundamentais para entender React hooks como useState — o estado "vive" dentro da closure do componente.
Exercícios do Módulo 02
Fácil
Saudação Personalizada
Escreve uma função saudar(nome, hora) que retorna "Bom dia, [nome]!" se hora < 12, "Boa tarde" se < 19, "Boa noite" caso contrário.
function saudar(nome, hora) {
  // O teu código aqui
}
console.log(saudar("Ana", 9));  // "Bom dia, Ana!"
console.log(saudar("João", 15)); // "Boa tarde, João!"
function saudar(nome, hora) {
  if (hora < 12) return `Bom dia, ${nome}!`;
  if (hora < 19) return `Boa tarde, ${nome}!`;
  return `Boa noite, ${nome}!`;
}
Médio
Fábrica de Saudadores
Cria uma função criarSaudador(saudacao) que retorna uma função que aceita um nome e usa a saudação fornecida.
function criarSaudador(saudacao) {
  // Retorna uma arrow function
}

const olá = criarSaudador("Olá");
const oi = criarSaudador("Oi");
olá("Maria"); // "Olá, Maria!"
oi("Pedro");  // "Oi, Pedro!"
function criarSaudador(saudacao) {
  return nome => `${saudacao}, ${nome}!`;
}
Próximo módulo
📚 Arrays e Objetos
→
📚
JavaScript · 03
Arrays e Objetos
Manipulação de arrays com map, filter, reduce. Objetos, desestruturação e spread operator.
📖 10 lições
✏️ 8 exercícios
3.1 Arrays — criação e métodos básicos ▾

Arrays são listas ordenadas de valores. Podem conter qualquer tipo de dado.

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

// Acesso por índice (começa em 0)
nums[0]; // 1
nums[nums.length - 1]; // 5 (último)

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

// Outros métodos
nums.includes(3);  // true
nums.indexOf(3);   // 2
nums.join(" - ");  // "1 - 2 - 3 - 4 - 5"
nums.reverse();    // inverte (muta o array!)
nums.slice(1, 3);  // [2, 3] (não muta)
3.2 map, filter e reduce ▾

Os três métodos funcionais mais importantes. Nunca mutam o array original — retornam sempre um novo valor.

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

// map — transforma cada elemento
const dobros = nums.map(n => n * 2);
// [2, 4, 6, 8, 10]

// filter — seleciona elementos
const pares = nums.filter(n => n % 2 === 0);
// [2, 4]

// reduce — acumula num único valor
const soma = nums.reduce((acc, n) => acc + n, 0);
// 15

// Encadear (chaining)
const resultado = nums
  .filter(n => n % 2 !== 0)  // [1,3,5]
  .map(n => n * n)              // [1,9,25]
  .reduce((acc, n) => acc + n, 0); // 35
3.3 Objetos — criação e acesso ▾

Objetos são coleções de pares chave-valor. São a estrutura de dados mais comum em JavaScript.

const pessoa = {
  nome: "Ana",
  idade: 28,
  cidade: "Lisboa",
  ativo: true
};

// Acesso — dot notation ou bracket notation
pessoa.nome;          // "Ana"
pessoa["idade"];      // 28

// Adicionar / modificar / apagar
pessoa.email = "ana@mail.pt";
pessoa.idade = 29;
delete pessoa.ativo;

// Verificar se propriedade existe
"nome" in pessoa; // true

// Listar chaves / valores
Object.keys(pessoa);    // ["nome", "idade", ...]
Object.values(pessoa);  // ["Ana", 29, ...]
Object.entries(pessoa); // [["nome","Ana"], ...]
3.4 Desestruturação e Spread ▾

A desestruturação extrai valores de arrays e objetos de forma concisa. O spread (...) copia ou expande elementos.

// Desestruturação de objetos
const { nome, idade } = pessoa;
// Renomear
const { nome: nomeCompleto } = pessoa;
// Valor por defeito
const { pais = "Portugal" } = pessoa;

// Desestruturação de arrays
const [primeiro, segundo, ...resto] = [1, 2, 3, 4];
// primeiro=1, segundo=2, resto=[3,4]

// Spread — copiar objetos
const pessoaAtualizada = { ...pessoa, idade: 30 };

// Spread — juntar arrays
const todos = [...[1,2], ...[3,4]]; // [1,2,3,4]

// Desestruturação em parâmetros
function mostrar({ nome, idade }) {
  console.log(`${nome} tem ${idade} anos`);
}
Exercícios do Módulo 03
Fácil
Dobrar os Elementos
Usa Array.map() para criar uma nova array onde cada número é o dobro do original.
const numeros = [1, 2, 3, 4, 5];
const dobros = numeros.map(/* aqui */);
console.log(dobros); // [2, 4, 6, 8, 10]
const dobros = numeros.map(n => n * 2);
Médio
Filtrar Adultos
Usa .filter() para retornar apenas as pessoas com 18 ou mais anos.
const pessoas = [
  { nome: "Ana", idade: 17 },
  { nome: "João", idade: 24 },
  { nome: "Rita", idade: 15 },
  { nome: "Pedro", idade: 32 }
];
const adultos = pessoas.filter(/* aqui */);
const adultos = pessoas.filter(p => p.idade >= 18);
Difícil
Soma com Reduce
Usa .reduce() para calcular o total de um carrinho de compras.
const carrinho = [
  { produto: "Livro", preco: 12.99 },
  { produto: "Caneta", preco: 1.50 },
  { produto: "Caderno", preco: 5.99 }
];
const total = carrinho.reduce(/* aqui */, 0);
console.log(total.toFixed(2)); // "20.48"
const total = carrinho.reduce((acc, item) => acc + item.preco, 0);
Próximo módulo
⚡ Assíncrono: Promises e Async/Await
→
⚡
JavaScript · 04
Assíncrono: Promises e Async/Await
Como funciona o event loop. Promises, .then()/.catch(), e a sintaxe moderna async/await.
📖 7 lições
✏️ 5 exercícios
4.1 O Event Loop — como o JS é single-thread ▾

JavaScript é single-threaded — executa uma coisa de cada vez. O event loop é o mecanismo que permite executar código assíncrono sem bloquear a thread principal.

console.log("1 - Início");

setTimeout(() => {
  console.log("3 - setTimeout (async)");
}, 0); // mesmo com 0ms, vai para a fila!

console.log("2 - Fim do código síncrono");

// Output:
// 1 - Início
// 2 - Fim do código síncrono
// 3 - setTimeout (async)
Operações como fetch, setTimeout, leitura de ficheiros e eventos do DOM são assíncronos — não bloqueiam o código que vem a seguir.
4.2 Promises — estados e encadeamento ▾

Uma Promise representa um valor que ainda não está disponível, mas estará no futuro. Tem três estados: pending, fulfilled ou rejected.

// Criar uma Promise
const promessa = new Promise((resolve, reject) => {
  const sucesso = true;
  if (sucesso) {
    resolve("Deu certo!");
  } else {
    reject(new Error("Algo correu mal"));
  }
});

// Consumir com .then() / .catch() / .finally()
promessa
  .then(resultado => console.log(resultado))
  .catch(erro => console.error(erro.message))
  .finally(() => console.log("Terminado"));

// Promise.all — esperar por várias promises
const resultados = await Promise.all([promessa1, promessa2]);
4.3 Async/Await — sintaxe moderna ▾

async/await é açúcar sintático sobre Promises. Torna o código assíncrono mais legível — parece código síncrono.

// Função assíncrona
async function buscarUtilizador(id) {
  try {
    const resposta = await fetch(
      `https://jsonplaceholder.typicode.com/users/${id}`
    );

    if (!resposta.ok) {
      throw new Error(`Erro HTTP: ${resposta.status}`);
    }

    const utilizador = await resposta.json();
    return utilizador;

  } catch (erro) {
    console.error("Falhou:", erro.message);
    return null;
  }
}

// Usar
const user = await buscarUtilizador(1);
console.log(user.name);
Exercícios do Módulo 04
Médio
Promise Básica
Cria uma função esperar(ms) que retorna uma Promise que resolve após ms milissegundos.
function esperar(ms) {
  return new Promise(/* aqui */);
}

esperar(1000).then(() => {
  console.log("Passou 1 segundo!");
});
function esperar(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}
Difícil
Fetch com Async/Await
Escreve uma função assíncrona que vai buscar dados de uma API pública e trata erros com try/catch.
async function buscarPost(id) {
  // URL: https://jsonplaceholder.typicode.com/posts/{id}
  // Usa try/catch e verifica resposta.ok
}

buscarPost(1).then(p => console.log(p.title));
async function buscarPost(id) {
  try {
    const res = await fetch(`https://jsonplaceholder.typicode.com/posts/${id}`);
    if (!res.ok) throw new Error(`Erro ${res.status}`);
    return await res.json();
  } catch (e) {
    console.error(e.message);
    return null;
  }
}
Próximo módulo
🌐 DOM e Eventos
→
🌐
JavaScript · 05
DOM e Eventos
Manipular o HTML com JavaScript. querySelector, addEventListener, criar e remover elementos.
📖 9 lições
✏️ 7 exercícios
5.1 Selecionar elementos do DOM ▾

O DOM (Document Object Model) representa o HTML como uma árvore de objetos que o JavaScript pode manipular.

// Selecionar um único elemento
const titulo = document.querySelector("h1");
const botao = document.querySelector("#meu-botao");
const card = document.querySelector(".card");

// Selecionar múltiplos elementos
const items = document.querySelectorAll("li");
items.forEach(item => console.log(item.textContent));

// Métodos clássicos (ainda úteis)
document.getElementById("app");
document.getElementsByClassName("card");
5.2 Modificar elementos ▾

Depois de selecionar um elemento, podes alterar o seu conteúdo, atributos e estilos.

const el = document.querySelector("#titulo");

// Conteúdo
el.textContent = "Novo título";     // só texto
el.innerHTML = "<em>Itálico</em>"; // com HTML

// Atributos
el.setAttribute("data-id", "42");
el.getAttribute("data-id"); // "42"
el.href = "https://exemplo.pt";

// Classes CSS
el.classList.add("ativo");
el.classList.remove("ativo");
el.classList.toggle("ativo");
el.classList.contains("ativo"); // true/false

// Estilos inline
el.style.color = "red";
el.style.display = "none";
5.3 Eventos — addEventListener ▾

Eventos permitem que o JavaScript reaja a interações do utilizador como cliques, teclas e movimentos do rato.

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

// Adicionar listener
btn.addEventListener("click", (evento) => {
  console.log("Clicado!", evento.target);
});

// Eventos comuns
// "click", "dblclick", "mouseover", "mouseout"
// "keydown", "keyup", "input", "change"
// "submit", "focus", "blur", "scroll"

// Prevenir comportamento padrão
form.addEventListener("submit", (e) => {
  e.preventDefault(); // evita reload da página
  // processar formulário
});

// Remover listener
const handler = () => console.log("clique");
btn.addEventListener("click", handler);
btn.removeEventListener("click", handler);
5.4 Criar e remover elementos dinamicamente ▾

Podes criar novos elementos HTML com JavaScript e adicioná-los ao DOM em qualquer momento.

// Criar elemento
const li = document.createElement("li");
li.textContent = "Novo item";
li.classList.add("item");

// Adicionar ao DOM
const lista = document.querySelector("ul");
lista.appendChild(li);     // no fim
lista.prepend(li);         // no início

// innerHTML — criar múltiplos elementos
lista.innerHTML = `
  <li>Primeiro</li>
  <li>Segundo</li>
`;

// Remover elemento
li.remove();

// Exemplo prático — lista de tarefas
function adicionarTarefa(texto) {
  const li = document.createElement("li");
  li.textContent = texto;
  li.addEventListener("click", () => li.remove());
  lista.appendChild(li);
}
Exercícios do Módulo 05
Médio
Contador Interativo
Cria uma página com um contador. Ao clicar nos botões "+", "-" e "Reset", o valor deve atualizar no ecrã.
<!-- HTML -->
<p id="valor">0</p>
<button id="inc">+</button>
<button id="dec">-</button>
<button id="reset">Reset</button>

// JS — implementa a lógica aqui
let count = 0;
const display = document.querySelector("#valor");
// Adiciona os event listeners...
let count = 0;
const display = document.querySelector("#valor");

document.querySelector("#inc").addEventListener("click", () => {
  display.textContent = ++count;
});
document.querySelector("#dec").addEventListener("click", () => {
  display.textContent = --count;
});
document.querySelector("#reset").addEventListener("click", () => {
  count = 0;
  display.textContent = count;
});
Próximo módulo
✨ ES6+ Funcionalidades Modernas
→
✨
JavaScript · 06
ES6+ Funcionalidades Modernas
Template literals, desestruturação, módulos (import/export), classes e muito mais.
📖 8 lições
✏️ 5 exercícios
6.1 Template Literals e Tagged Templates ▾

Template literals (backticks) permitem interpolação de variáveis e strings multilinha de forma elegante.

const nome = "Ana";
const idade = 28;

// Interpolação
const msg = `Olá, ${nome}! Tens ${idade} anos.`;

// Expressões dentro de ${}
const res = `${2 + 2} é o resultado`; // "4 é o resultado"

// String multilinha
const html = `
  <div class="card">
    <h2>${nome}</h2>
    <p>${idade} anos</p>
  </div>
`;

// Chamada de função dentro
const maiusc = `Nome: ${nome.toUpperCase()}`;
6.2 Classes em JavaScript ▾

Classes são açúcar sintático sobre o sistema de protótipos do JavaScript. Tornam o código orientado a objetos mais legível.

class Animal {
  constructor(nome, especie) {
    this.nome = nome;
    this.especie = especie;
  }

  apresentar() {
    return `Sou ${this.nome}, um ${this.especie}`;
  }

  static criar(nome, especie) {
    return new Animal(nome, especie);
  }
}

// Herança
class Cao extends Animal {
  constructor(nome) {
    super(nome, "cão"); // chama o construtor pai
  }

  ladrar() {
    return "Au au!";
  }
}

const rex = new Cao("Rex");
rex.apresentar(); // "Sou Rex, um cão"
rex.ladrar();     // "Au au!"
6.3 Módulos: import e export ▾

Módulos ES6 permitem dividir o código em ficheiros reutilizáveis com export e import.

// utils.js — exportar
export const PI = 3.14159;

export function somar(a, b) {
  return a + b;
}

export default function principal() {
  return "função principal";
}

// main.js — importar
import principal from "./utils.js";         // default
import { PI, somar } from "./utils.js";      // named
import * as utils from "./utils.js";        // tudo
import { somar as add } from "./utils.js"; // renomear
6.4 Optional Chaining e Nullish Coalescing ▾

Duas funcionalidades modernas que tornam o acesso a dados aninhados muito mais seguro e conciso.

const user = {
  nome: "Ana",
  endereco: {
    cidade: "Lisboa"
  }
};

// Optional Chaining (?.) — não lança erro se undefined
user?.nome;                    // "Ana"
user?.endereco?.rua;           // undefined (sem erro!)
user?.telefone?.numero;        // undefined
user?.metodo?.();              // chama se existir

// Nullish Coalescing (??) — valor por defeito
// Só substitui null e undefined (não 0 ou "")
user?.pais ?? "Portugal";     // "Portugal"
0 ?? "padrão";                 // 0 (diferente de ||)
0 || "padrão";                 // "padrão" (0 é falsy)

// Combinado — muito comum em React
const cidade = user?.endereco?.cidade ?? "Desconhecida";
Exercícios do Módulo 06
Médio
Classe ContaBancária
Cria uma classe ContaBancaria com saldo inicial, métodos depositar(), levantar() (sem saldo negativo) e verSaldo().
class ContaBancaria {
  constructor(titular, saldoInicial = 0) {
    // O teu código aqui
  }
  depositar(valor) { /* ... */ }
  levantar(valor) { /* ... */ }
  verSaldo() { /* ... */ }
}

const conta = new ContaBancaria("Ana", 100);
conta.depositar(50);
conta.levantar(200); // "Saldo insuficiente"
conta.verSaldo();    // "Ana: 150€"
class ContaBancaria {
  constructor(titular, saldoInicial = 0) {
    this.titular = titular;
    this.saldo = saldoInicial;
  }
  depositar(valor) {
    this.saldo += valor;
  }
  levantar(valor) {
    if (valor > this.saldo) return console.log("Saldo insuficiente");
    this.saldo -= valor;
  }
  verSaldo() {
    console.log(`${this.titular}: ${this.saldo}€`);
  }
}
🎉 JavaScript Completo!
Próximo: Módulo 07–12
⚛️ Começa com React →
→