<h2>Fundamentos de Classes em JavaScript</h2>
<p>Classes em JavaScript são açúcar sintático construído sobre o modelo de protótipos, introduzidas na ES6 (2015). Diferentemente de linguagens clássicas, JavaScript usa protótipos internamente, mas as classes oferecem uma sintaxe familiar e mais legível para definir objetos e suas estruturas. Compreender essa abstração é essencial para trabalhar com código moderno e profissional.</p>
<p>Uma classe é um molde para criar objetos com propriedades e métodos. Sua sintaxe é direta: declare com <code>class</code>, defina o <code>constructor</code> para inicializar propriedades e crie métodos para comportamentos. Veja um exemplo prático:</p>
<pre><code class="language-javascript">class Veiculo {
constructor(marca, modelo) {
this.marca = marca;
this.modelo = modelo;
this.velocidade = 0;
}
acelerar(incremento) {
this.velocidade += incremento;
console.log(${this.marca} ${this.modelo} acelerando para ${this.velocidade} km/h);
}
frear() {
this.velocidade = 0;
console.log(${this.marca} ${this.modelo} freado completamente);
}
}
const carro = new Veiculo('Toyota', 'Corolla');
carro.acelerar(60);
carro.frear();</code></pre>
<h3>Métodos e Propriedades Estáticas</h3>
<p>Métodos estáticos pertencem à classe, não às instâncias. Úteis para funcionalidades utilitárias que não dependem de dados de uma instância específica. Use a palavra-chave <code>static</code>:</p>
<pre><code class="language-javascript">class Calculadora {
static somar(a, b) {
return a + b;
}
static mediaAritmetica(numeros) {
const soma = numeros.reduce((acc, num) => acc + num, 0);
return soma / numeros.length;
}
}
console.log(Calculadora.somar(5, 3)); // 8
console.log(Calculadora.mediaAritmetica([10, 20, 30])); // 20</code></pre>
<h2>Herança e Composição</h2>
<p>A herança permite que uma classe reutilize e estenda código de outra classe. Use <code>extends</code> para herdar e <code>super()</code> para acessar o construtor da classe pai. Este padrão é fundamental em arquiteturas orientadas a objeto, mas use com moderação — frequentemente composição é mais flexível que herança profunda.</p>
<pre><code class="language-javascript">class Veiculo {
constructor(marca) {
this.marca = marca;
}
info() {
return Marca: ${this.marca};
}
}
class Carro extends Veiculo {
constructor(marca, portas) {
super(marca);
this.portas = portas;
}
info() {
return ${super.info()} | Portas: ${this.portas};
}
}
class Moto extends Veiculo {
constructor(marca, cilindrada) {
super(marca);
this.cilindrada = cilindrada;
}
info() {
return ${super.info()} | Cilindrada: ${this.cilindrada}cc;
}
}
const carro = new Carro('Honda', 4);
const moto = new Moto('Yamaha', 600);
console.log(carro.info()); // Marca: Honda | Portas: 4 console.log(moto.info()); // Marca: Yamaha | Cilindrada: 600cc</code></pre>
<h3>Evitando Hierarquias Profundas</h3>
<p>Em produção, evite heranças com mais de 2 ou 3 níveis. Prefira composição: injete comportamentos através de objetos passados ao construtor. Isso torna o código mais testável e flexível:</p>
<pre><code class="language-javascript">class MotorEletrico {
ligar() {
return 'Motor elétrico ligado silenciosamente';
}
}
class Bateria {
carga = 100;
descarregar() {
this.carga -= 10;
return Bateria em ${this.carga}%;
}
}
class VeiculoEletrico {
constructor(motor, bateria) {
this.motor = motor;
this.bateria = bateria;
}
ligarMotor() {
return this.motor.ligar();
}
usar() {
return this.bateria.descarregar();
}
}
const tesla = new VeiculoEletrico(new MotorEletrico(), new Bateria());
console.log(tesla.ligarMotor());
console.log(tesla.usar());</code></pre>
<h2>Encapsulamento: Privacidade e Controle</h2>
<p>O encapsulamento protege dados internos de acesso direto, expondo apenas o necessário através de uma interface pública. Em JavaScript moderno, propriedades privadas usam o prefixo <code>#</code>. Isso garante que apenas métodos internos à classe possam acessá-las, prevenindo modificações acidentais e facilitando refatoração segura em produção.</p>
<pre><code class="language-javascript">class ContaBancaria {
#saldo = 0;
#historico = [];
constructor(titular, saldoInicial = 0) {
this.titular = titular;
this.#saldo = saldoInicial;
this.#historico.push({ operacao: 'Abertura', valor: saldoInicial, data: new Date() });
}
depositar(valor) {
if (valor <= 0) {
throw new Error('Valor deve ser positivo');
}
this.#saldo += valor;
this.#historico.push({ operacao: 'Depósito', valor, data: new Date() });
return Depósito de R$${valor} realizado. Saldo: R$${this.#saldo};
}
sacar(valor) {
if (valor > this.#saldo) {
throw new Error('Saldo insuficiente');
}
this.#saldo -= valor;
this.#historico.push({ operacao: 'Saque', valor, data: new Date() });
return Saque de R$${valor} realizado. Saldo: R$${this.#saldo};
}
obterSaldo() {
return this.#saldo;
}
obterHistorico() {
return [...this.#historico];
}
}
const conta = new ContaBancaria('João', 1000);
console.log(conta.depositar(500));
console.log(conta.sacar(200));
console.log(conta.obterSaldo());
// conta.#saldo = -9999; // Erro: propriedade privada é inacessível</code></pre>
<h3>Getters e Setters</h3>
<p>Getters e setters permitem validação e lógica customizada ao acessar propriedades, mantendo a sintaxe de propriedades simples. Essencial para classes em produção que precisam de regras de negócio:</p>
<pre><code class="language-javascript">class Usuario {
#email;
#idade;
constructor(nome, email, idade) {
this.nome = nome;
this.email = email;
this.idade = idade;
}
get email() {
return this.#email;
}
set email(novoEmail) {
if (!novoEmail.includes('@')) {
throw new Error('Email inválido');
}
this.#email = novoEmail;
}
get idade() {
return this.#idade;
}
set idade(novaIdade) {
if (novaIdade < 0 || novaIdade > 150) {
throw new Error('Idade inválida');
}
this.#idade = novaIdade;
}
}
const usuario = new Usuario('Maria', 'maria@email.com', 28);
console.log(usuario.email);
usuario.idade = 29;
console.log(usuario.idade);
// usuario.email = 'invalido'; // Erro: Email inválido</code></pre>
<h2>Boas Práticas em Produção</h2>
<p>Em ambientes reais, siga estas diretrizes: (1) <strong>Use encapsulamento por padrão</strong> — propriedades privadas protegem sua arquitetura; (2) <strong>Prefira composição a herança profunda</strong> — é mais simples de entender e testar; (3) <strong>Valide dados nos setters e construtores</strong> — evita estados inválidos; (4) <strong>Documente com JSDoc</strong> — facilita manutenção futura.</p>
<pre><code class="language-javascript">/**
- Classe que representa um Produto no sistema de e-commerce
- @class Produto
- @param {string} nome - Nome do produto
- @param {number} preco - Preço em reais
- @param {number} estoque - Quantidade em estoque
*/
class Produto {
#preco;
#estoque;
constructor(nome, preco, estoque) {
this.nome = nome;
this.preco = preco;
this.estoque = estoque;
}
get preco() {
return this.#preco;
}
set preco(valor) {
if (valor <= 0) throw new Error('Preço deve ser positivo');
this.#preco = valor;
}
/**
- Reduz estoque após venda
- @param {number} quantidade
- @returns {boolean} Sucesso da operação
*/
vender(quantidade) {
if (quantidade > this.#estoque) return false;
this.#estoque -= quantidade;
return true;
}
obterEstoque() {
return this.#estoque;
}
}
const produto = new Produto('Notebook', 3000, 5);
produto.vender(2);
console.log(produto.obterEstoque()); // 3</code></pre>
<h2>Conclusão</h2>
<p>Classes em JavaScript oferecem uma abordagem profissional e estruturada para organizar código. O domínio de <strong>herança com <code>extends</code> e <code>super</code></strong>, <strong>encapsulamento com propriedades privadas</strong> e <strong>getters/setters com validação</strong> é indispensável em projetos reais. Lembre-se: prefira composição quando possível, sempre valide dados e documente sua código — essas práticas garantem manutenibilidade a longo prazo.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Classes" target="_blank" rel="noopener noreferrer">MDN Web Docs - Classes</a></li>
<li><a href="https://tc39.es/ecma262/#sec-class-definitions" target="_blank" rel="noopener noreferrer">ECMAScript 2022 Specification - Class</a></li>
<li><a href="https://github.com/getify/You-Dont-Know-JS" target="_blank" rel="noopener noreferrer">You Don't Know JS Yet: Objects & Classes</a></li>
<li><a href="https://javascript.info/classes" target="_blank" rel="noopener noreferrer">JavaScript.info - Classes</a></li>
<li><a href="https://www.typescriptlang.org/docs/handbook/2/classes.html" target="_blank" rel="noopener noreferrer">TypeScript Handbook - Classes</a></li>
</ul>