Page cover

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

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 Carro {
  constructor(marca, modelo) {
    this.marca = marca;
    this.modelo = modelo;
  }

  acelerar() {
    console.log(`${this.marca} ${this.modelo} está acelerando!`);
  }
}

🔄 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

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

O 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()

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

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:

Conceito
Explicação rápida

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