7.8.7 - Classes e Objetos
🏛️ Classes em JavaScript — Por trás da cortina
🏛️ Classes em JavaScript — Por trás da cortina
JavaScript tem uma carinha nova com class
, mas por dentro… é o bom e velho sistema de protótipos! 🧠
Ou seja, as classes são só uma forma mais moderna e organizada de escrever o que antes era feito com funções construtoras + prototype.
✨ Diferença entre class
e prototype
class
e prototype
Ambos funcionam, mas a sintaxe class
foi criada para parecer com outras linguagens como Java ou Python — mais limpa e fácil de entender.
Por baixo dos panos:
class Pessoa {
falar() {
console.log("Oi!");
}
}
É quase igual a:
function Pessoa() {}
Pessoa.prototype.falar = function () {
console.log("Oi!");
};
Mesmo efeito, escrita diferente! 🎭
🧱 Definindo propriedades e métodos com class
class
class Carro {
constructor(marca, modelo) {
this.marca = marca;
this.modelo = modelo;
}
acelerar() {
console.log(`${this.marca} ${this.modelo} está acelerando!`);
}
}
🔄 constructor()
constructor()
É o método especial que roda automaticamente quando a classe é instanciada com new
.
🧍 Classe e instância
const meuCarro = new Carro("Toyota", "Corolla");
meuCarro.acelerar(); // Toyota Corolla está acelerando!
➡️ meuCarro
é uma instância da classe Carro
.
🔐 Campos públicos e privados
🌐 Públicos (acessíveis de fora):
class Pessoa {
nome = "Lucas"; // público
}
🔒 Privados (não acessíveis de fora):
class Conta {
#saldo = 0; // privado
verSaldo() {
return this.#saldo;
}
}
⚠️ Campos privados usam
#
e só podem ser acessados dentro da própria classe.
📥 Campos de acesso: get
e set
get
e set
Controlam a leitura e modificação de propriedades:
class Produto {
constructor(nome) {
this._nome = nome;
}
get nome() {
return this._nome.toUpperCase();
}
set nome(novoNome) {
this._nome = novoNome;
}
}
🧠 O this
dentro de classes
this
dentro de classesO this
sempre se refere à instância da classe:
class Animal {
constructor(nome) {
this.nome = nome;
}
falar() {
console.log(`${this.nome} está falando`);
}
}
🧪 Usando funções no construtor vs métodos da classe
❌ Funções dentro do constructor (menos performático):
class Pessoa {
constructor() {
this.falar = function () {
console.log("Oi");
};
}
}
Cada instância terá sua própria cópia de falar
.
✅ Melhor: declarar como método da classe
class Pessoa {
falar() {
console.log("Oi");
}
}
Mais leve e compartilhado via protótipo.
💡 Hoisting e Class Expressions
As classes não são içadas (hoisting) como funções. Você não pode usar antes de declarar.
const MeuObjeto = class {
falar() {
console.log("Hello");
}
};
const obj = new MeuObjeto();
🧾 Observação: Class Expressions — anônimas e nomeadas
Você já viu classes declaradas assim? 👇
class Pessoa {
falar() {
console.log("Olá!");
}
}
Essa é a forma mais comum — declaração de classe. Mas também podemos criar expressões de classe, que funcionam de maneira parecida às funções anônimas ou funções com nome.
🟢 Class Expression Anônima
const Animal = class {
andar() {
console.log("O animal está andando.");
}
};
const gato = new Animal();
gato.andar(); // O animal está andando.
✅ A classe não tem nome interno, só é acessada pela constante Animal
.
🟡 Class Expression Nomeada
const Veiculo = class Carro {
acelerar() {
console.log("Vruuum!");
}
};
Você pode pensar: “Mas por que colocar nome se já tem Veiculo
?” 🤔
Boa pergunta! A resposta:
➡️ O nome Carro
só existe dentro da própria classe — útil para recursividade ou debug (erros com nome da classe).
console.log(Veiculo.name); // Carro
❗Mas fora da classe, Carro
não existe:
console.log(Carro); // ReferenceError: Carro is not defined ❌
.name
é uma propriedade padrão em funções e classes no JavaScript, e no caso de class expressions nomeadas, ela é automaticamente definida com o nome fornecido na definição da classe.Quando a classe não tem um nome explícito, o JavaScript infere o nome da função com base na variável que a armazena.
🧠 Quando usar class expressions?
✅ São úteis para:
Criar classes dinâmicas (ex: dentro de funções ou retornos)
Injetar comportamentos diferentes de forma mais flexível
Evitar poluir o escopo com nomes globais
📌 Resumo de Class Expression:
Você pode criar class expressions com ou sem nome.
Anônimas: mais simples, usadas em variáveis.
Nomeadas: úteis para identificar melhor no debug.
O nome não é acessível fora da classe.
🧬 Herança com extends
e super()
extends
e super()
class Pessoa {
constructor(nome) {
this.nome = nome;
}
falar() {
console.log(`${this.nome} está falando`);
}
}
class Professor extends Pessoa {
constructor(nome, materia) {
super(nome); // chama o constructor da superclasse
this.materia = materia;
}
falar() {
super.falar(); // chama o método da superclasse
console.log(`E ensina ${this.materia}`);
}
}
🔁 Isso é método sobrescrito (override).
🧪 instanceof
instanceof
Usado para verificar se um objeto é instância de uma classe:
const p = new Professor("Ana", "Matemática");
console.log(p instanceof Professor); // true ✅
console.log(p instanceof Pessoa); // true ✅
⚙️ Campos e métodos estáticos
class App {
static nome = "MeuApp";
static iniciar() {
console.log("Iniciando app...");
}
}
console.log(App.nome);
App.iniciar();
⚠️ Não são acessíveis pelas instâncias, só pela própria classe.
⚡ Bloco de inicialização estático
Código que roda uma vez só quando a classe é carregada:
class Sistema {
static config = {};
static {
Sistema.config = { tema: "claro" };
console.log("Configuração inicial definida.");
}
}
🧱 Classes privadas e propriedades estáticas privadas
class Banco {
static #taxa = 0.1;
static mostrarTaxa() {
return Banco.#taxa;
}
}
🧠 Como tudo isso funciona por trás?
Lembre-se: classes são só açúcar sintático. Por trás, o JavaScript ainda usa:
Protótipos
Referências de memória
Herança via
[[Prototype]]
(a cadeia prototípica)
📌 Resumo final:
class
Forma moderna de declarar objetos
constructor()
Inicializa o objeto
this
Se refere à instância
extends
+ super()
Herança de outra classe
static
Pertence à classe, não à instância
Campos privados
Usam #
Métodos públicos
Acessíveis em toda instância
instanceof
Verifica herança
Last updated