404 Not Found

404 Not Found


nginx

Classes e Módulos em JavaScript

Conforme os projetos crescem, você precisa de mais do que funções e variáveis espalhadas — precisa de estrutura organizada de código. Classes fornecem padrões orientados a objetos, e Módulos fornecem isolamento de código no nível de arquivo. Juntos, formam a base de projetos JS modernos.


Sintaxe de Classe

Uma Classe é um modelo para criar objetos — açúcar sintático sobre funções construtoras.

HTML
<script>
class NomeClasse {
  constructor(params) {
    this.propriedade = params;
  }
  metodo() {
    // ...
  }
}
</script>

Exemplo: Criando uma Classe Aluno

HTML
<div id="output" style="padding: 10px; border: 1px solid #ccc;"></div>

<script>
const output = document.getElementById('output');

class Aluno {
  constructor(nome, idade, serie) {
    this.nome = nome;
    this.idade = idade;
    this.serie = serie;
  }

  apresentar() {
    return 'Meu nome é ' + this.nome + ', tenho ' + this.idade + ' anos, estou no ' + this.serie + '.';
  }

  estudar(materia) {
    return this.nome + ' está estudando ' + materia + '.';
  }
}

const a1 = new Aluno('Alice', 12, '6º ano');
const a2 = new Aluno('Bob', 11, '5º ano');

output.textContent = a1.apresentar() + '\n' + a2.apresentar() + '\n' + a1.estudar('Matemática');
</script>
▶ Experimente
💡 class é essencialmente açúcar sintático sobre funções construtoras + protótipos. new Aluno() funciona igual ao antigo new function Aluno(), mas a sintaxe é mais limpa e intuitiva.


Propriedades e Métodos

Propriedades e Métodos de Instância

Propriedades e métodos definidos com this.xxx dentro do constructor pertencem à instância — cada objeto recebe sua própria cópia.

Métodos Estáticos

Métodos definidos com a palavra-chave static pertencem à classe em si, não às instâncias. Chame-os via NomeClasse.metodo().

Getters e Setters

Use as palavras-chave get e set para definir "propriedades virtuais" — funções que executam automaticamente na leitura/escrita.

HTML
<div id="output" style="white-space: pre; font-family: monospace; padding: 10px; border: 1px solid #ccc;"></div>
<script>
const output = document.getElementById('output');

class Pessoa {
  constructor(primeiroNome, sobrenome) {
    this.primeiroNome = primeiroNome;
    this.sobrenome = sobrenome;
  }

  get nomeCompleto() {
    return this.primeiroNome + ' ' + this.sobrenome;
  }

  set nomeCompleto(valor) {
    const partes = valor.split(' ');
    this.primeiroNome = partes[0];
    this.sobrenome = partes[1];
  }
}

const p = new Pessoa('João', 'Silva');
output.textContent = 'nomeCompleto: ' + p.nomeCompleto + '\n';
p.nomeCompleto = 'Maria Santos';
output.textContent += 'Após alteração: ' + p.nomeCompleto;
</script>

Exemplo: Métodos Estáticos e Getters/Setters

HTML
<div id="output" style="white-space: pre; font-family: monospace; padding: 10px; border: 1px solid #ccc;"></div>

<script>
const output = document.getElementById('output');

class Circulo {
  static contagem = 0;

  constructor(raio) {
    this.raio = raio;
    Circulo.contagem++;
  }

  get area() {
    return Math.PI * this.raio * this.raio;
  }

  get diametro() {
    return this.raio * 2;
  }

  set diametro(valor) {
    this.raio = valor / 2;
  }

  static criarUnidade() {
    return new Circulo(1);
  }
}

const c1 = new Circulo(5);
const c2 = new Circulo(10);
const c3 = Circulo.criarUnidade();

output.textContent = 'Círculo com raio 5:\n';
output.textContent += '  Área: ' + c1.area.toFixed(2) + '\n';
output.textContent += '  Diâmetro: ' + c1.diametro + '\n';
output.textContent += '  Definir diâmetro como 20:\n';
c1.diametro = 20;
output.textContent += '  Novo raio: ' + c1.raio + '\n\n';
output.textContent += 'Total de círculos criados: ' + Circulo.contagem + '\n';
output.textContent += 'Raio do círculo unitário: ' + c3.raio;
</script>
▶ Experimente

Herança

extends permite que uma classe filha herde propriedades e métodos de uma classe pai. super chama o construtor ou métodos do pai.

Exemplo: Demonstração de Herança

HTML
<div id="output" style="white-space: pre; font-family: monospace; padding: 10px; border: 1px solid #ccc;"></div>

<script>
const output = document.getElementById('output');

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

  falar() {
    return this.nome + ' diz: ' + this.som;
  }
}

class Cachorro extends Animal {
  constructor(nome, raca) {
    super(nome, 'Au Au');
    this.raca = raca;
  }

  buscar(item) {
    return this.nome + ' buscou o ' + item;
  }
}

class Gato extends Animal {
  constructor(nome, interno) {
    super(nome, 'Miau');
    this.interno = interno;
  }

  ronronar() {
    return this.nome + ' está ronronando...';
  }
}

const cachorro = new Cachorro('Rex', 'Shiba Inu');
const gato = new Gato('Miau', true);

output.textContent = cachorro.falar() + '\n';
output.textContent += cachorro.buscar('frisbee') + '\n';
output.textContent += gato.falar() + '\n';
output.textContent += gato.ronronar();
</script>
▶ Experimente
💡 No constructor de uma classe filha, você deve chamar super() antes de usar this — porque até o pai ser inicializado, o this do filho não existe. Esta é a regra mais fácil de esquecer ao aprender herança.


Módulos ES

Módulos são a unidade de organização de código do JS. Um módulo = um arquivo. Variáveis dentro de um módulo são privadas por padrão — apenas itens explicitamente exportados são acessíveis externamente.

Exportações/Importações Nomeadas

HTML
<script>
// math.js
export const PI = 3.14;
export function somar(a, b) { return a + b; }

// app.js
import { PI, somar } from './math.js';
</script>

Exportações/Importações Padrão

HTML
<script>
// logger.js
export default function log(msg) { console.log(msg); }

// app.js
import log from './logger.js';
</script>

Usando Módulos em HTML

Simplesmente adicione type="module" à tag script.

HTML
<script type="module">
  import { somar } from './math.js';
  console.log(somar(1, 2));
</script>
⚠️ Arquivos de módulo são cacheados pelos navegadores e sujeitos à política de mesma origem. Abrir um arquivo HTML local pode falhar ao carregar módulos — você precisa servir via um servidor HTTP.

Exemplo: Simulação de Módulo em Arquivo Único (Módulo Inline)

Em projetos reais, módulos devem ser divididos em arquivos separados. Aqui simulamos dentro de um único arquivo HTML usando type="module".

HTML
<div id="output" style="padding: 10px; border: 1px solid #ccc;"></div>

<script type="module">
const output = document.getElementById('output');

const calculadora = {
  somar(a, b) { return a + b; },
  subtrair(a, b) { return a - b; },
  multiplicar(a, b) { return a * b; },
  dividir(a, b) { return b !== 0 ? a / b : 'Não é possível dividir por zero'; }
};

const formatador = {
  moeda(valor) { return 'R$' + valor.toFixed(2); },
  porcentagem(valor) { return (valor * 100).toFixed(1) + '%'; }
};

const r1 = calculadora.somar(10, 20);
const r2 = calculadora.multiplicar(5, 4);
const r3 = calculadora.dividir(10, 3);

output.textContent = '10 + 20 = ' + r1 + '\n';
output.textContent += '5 × 4 = ' + r2 + '\n';
output.textContent += '10 ÷ 3 = ' + formatador.moeda(r3) + '\n';
output.textContent += '0.85 → ' + formatador.porcentagem(0.85);

// Em um projeto real você dividiria assim:
// calculadora.js → export { calculadora }
// formatador.js → export { formatador }
// main.js → import { calculadora } from './calculadora.js'
//           import { formatador } from './formatador.js'
</script>
▶ Experimente

📖 Resumo

  1. class é açúcar sintático sobre construtores; constructor é o inicializador, e métodos são definidos no protótipo
  2. Métodos static pertencem à classe, não às instâncias — ideais para métodos utilitários e de fábrica
  3. get/set definem propriedades virtuais que interceptam leituras/escritas para validação ou computação
  4. extends habilita herança; o constructor filho deve chamar super() primeiro
  5. Módulos ES usam export/import para isolamento e reuso de código; type="module" os habilita em HTML
  6. Módulos organizam código por funcionalidade, permitem carregamento preguiçoso e evitam poluição do namespace global

❓ Perguntas Frequentes

P: Qual a diferença real entre Classe e função construtora? R: Nenhuma diferença fundamental — Classe é açúcar sintático. Mas Classes têm algumas características: devem ser chamadas com new (não podem rodar como funções comuns), métodos são não enumeráveis, e o modo estrito é ativado por padrão. A sintaxe é mais limpa, então Classes são recomendadas.

P: Qual a diferença entre import e require? R: import é sintaxe de módulo ES — analisada estaticamente em tempo de compilação. require é CommonJS (Node.js) — carregada dinamicamente em tempo de execução. Navegadores suportam nativamente apenas módulos ES. import deve estar no nível superior; require pode estar em qualquer lugar.

P: É possível misturar exportações padrão e nomeadas? R: Sim. Um módulo pode ter uma exportação padrão e múltiplas exportações nomeadas: export default App; export const utils = {};. Importe com: import App, { utils } from './modulo.js'.

📝 Atividades

  1. Básico: Crie uma classe Retangulo com propriedades largura e altura, além dos métodos obterArea() e obterPerimetro().
  2. Intermediário: Adicione um getter get area() e setter set area(valor) ao Retangulo (definir área ajusta largura/altura proporcionalmente). Depois crie uma subclasse Quadrado que estenda Retangulo.
  3. Desafio: Projete uma classe GerenciadorEventos com métodos on(evento, callback), off(evento, callback) e emit(evento, dados) para simular um sistema simples de eventos (dica: use um objeto mapeando eventos para arrays de callbacks).
100%