7.8.4 - Classes e Objetos
🧬 Herança em JavaScript — O Poder de Reaproveitar Código!
🧬 Herança em JavaScript — O Poder de Reaproveitar Código!
A herança permite que um objeto "pegue emprestado" propriedades e comportamentos de outro. Isso evita repetição de código e ajuda a organizar melhor nossos programas. Em JavaScript, temos um jeito especial de fazer isso: herança prototipada.
💡 "Herança" é quando um objeto ou classe "filha" ganha tudo o que a classe "pai" tem — como poderes sendo passados de geração em geração! 🧙♂️➡️🧙♀️
🧱 Herança Prototipada: Como funciona?
No JavaScript, objetos herdam de outros objetos por meio de protótipos. Essa é a famosa cadeia de protótipos (prototype chain).
Quando tentamos acessar uma propriedade/método, o JS:
Procura no próprio objeto.
Se não encontrar, sobe para o protótipo (
__proto__).Continua subindo na cadeia até encontrar ou chegar no
null.
const animal = {
tipo: "Animal",
fazerSom() {
console.log("Som genérico...");
}
};
const cachorro = Object.create(animal);
cachorro.fazerSom(); // Som genérico...🧠
Object.create()cria um novo objeto que herda de outro.
🧪 Exemplo com função construtora
📌 Herdando com e sem parâmetros
🔁 Definindo o protótipo e a referência do construtor
📎 Sobrescrevendo um método
⚠️ Importante: Sempre que usar
Object.create()para herdar, lembre de corrigir a referênciaconstructor.
🧠 Observação importante: cuidado com o Object.create() e o constructor!
Object.create() e o constructor!Quando usamos Object.create() para criar herança entre objetos ou funções construtoras, estamos dizendo que o novo objeto deve herdar o protótipo de outro.
👀 Mas tem um detalhe importante que MUITA gente esquece:
O
constructordo novo protótipo continua apontando para o construtor original (pai) — não para o filho! ⚠️
Vamos ver isso na prática:
➡️ Isso acontece porque Object.create(Pessoa.prototype) cria um novo objeto cujo __proto__ é Pessoa.prototype. Então, o constructor é herdado de lá também.
🛠️ Como corrigir?
Basta redefinir manualmente o constructor da função filha:
Agora tudo fica certo:
📌 Por que isso é importante?
O constructor é usado por ferramentas, IDEs e o próprio JavaScript para entender qual função criou um objeto. Se essa referência estiver errada, pode causar:
Confusão na hora de debugar 🔍
Problemas em frameworks que usam
constructorautomaticamente 🔧Dificuldade na manutenção e leitura do código 😵💫
✅ Resumo rápido
Usou Object.create()
constructor aponta para o pai ❌
Redefina manualmente com Filho.prototype.constructor = Filho ✅
🧠 Observação: Entendendo Professor.prototype, Professor.constructor e Professor.prototype.constructor
Professor.prototype, Professor.constructor e Professor.prototype.constructorEssas três estruturas aparecem MUITO quando estamos lidando com herança e protótipos em JavaScript. Vamos entender cada uma delas de forma clara, com comparações e exemplos simples:
🧱 Professor.prototype
Professor.prototypeÉ o protótipo dos objetos que serão criados quando usamos new Professor().
Tudo o que colocamos aqui será compartilhado entre as instâncias criadas com essa função.
🧾 Professor.constructor
Professor.constructorIsso se refere ao construtor da função em si, ou seja, Function!
Lembre-se: em JavaScript, funções também são objetos — e o construtor das funções é Function.
🧬 Professor.prototype.constructor
Professor.prototype.constructorAqui está o ponto chave! Essa propriedade indica qual função construiu aquele protótipo.
Por padrão, ela aponta para a função construtora correta. Mas quando usamos Object.create() para fazer herança, ela pode acabar apontando para a função errada!
🧪 Recapitulando com uma tabela:
Professor.prototype
Protótipo dos objetos Professor
Objeto
Professor.constructor
Quem criou a função Professor
Function
Professor.prototype.constructor
Quem criou o protótipo do Professor
Professor (ou incorretamente Pessoa)
⚠️ Atenção: Confundir
constructorcomprototype.constructoré um dos erros mais comuns entre quem está começando com herança em JS! 😅
✅ Dica prática
Sempre que fizer herança com Object.create(), verifique se prototype.constructor está apontando corretamente.
Se não estiver, corrija manualmente:
🔍 Observação: O que retorna quando usamos apenas Professor.prototype?
Professor.prototype?Quando você acessa Professor.prototype diretamente no seu código, está consultando o objeto protótipo associado à função construtora Professor.
📦 Em outras palavras:
🟰 Retorna um objeto que servirá como base para todas as instâncias criadas com
new Professor().
🧠 O que tem dentro desse objeto?
Por padrão, ele começa assim:
Ou seja, ele contém:
A propriedade
constructor, que aponta de volta para a própria funçãoProfessor.
💡 Pra que serve esse objeto?
É nesse Professor.prototype que você pode adicionar métodos ou propriedades compartilhadas entre todas as instâncias da função.
✅ Ambos os objetos compartilham o mesmo método sem duplicar o código na memória!
📌 Por que isso é importante?
Entender o que Professor.prototype retorna é essencial para:
Trabalhar com herança corretamente
Criar métodos otimizados
Entender como funciona o encadeamento de protótipos
Evitar confusão com
__proto__eprototype.constructor
🛑 Atenção
Professor.prototypenão é o protótipo da função Professor. Ele é o protótipo que será usado pelas instâncias criadas comnew Professor()!
🔁 Já o Professor.__proto__ (com dois underlines) aponta para Function.prototype, pois Professor é uma função.
✅ Resumo rápido
Professor.prototype
Objeto usado como protótipo pelas instâncias criadas
new Professor().__proto__
Sempre é igual a Professor.prototype
📘 ECMAScript 2015 (ES6): Herança com classes
A sintaxe moderna com class facilita muito o uso da herança:
🔍 Como funciona por debaixo dos panos?
Mesmo com a sintaxe class, o JavaScript continua usando protótipos! A classe nada mais é que um açúcar sintático para facilitar a vida de quem programa.
🧩 Onde posso definir propriedades e métodos?
Dentro da função construtora
this.nome = "..."
Quando cada instância precisa de um valor diferente
No próprio construtor (estático)
MinhaClasse.algumaFuncao = function () {}
Quando o método é da classe, não do objeto
No protótipo
MinhaClasse.prototype.metodo = function () {}
Quando todas as instâncias compartilham o mesmo comportamento
🧭 Quando usar herança em JavaScript?
✔️ Use quando:
Vários objetos compartilham lógica comum.
Você quer reaproveitar métodos entre objetos semelhantes.
Precisa organizar melhor responsabilidades e comportamentos.
🚫 Evite quando:
Os objetos têm pouco em comum.
A herança deixa o código mais confuso do que ajuda.
Composição seria mais clara do que herança.
💬 Dica: Uma boa regra é "preferir composição à herança", mas usar herança quando o comportamento for realmente compartilhado e hierárquico!
✅ Resumo prático
call()
Pai.call(this)
Chama o construtor pai no contexto do filho
Object.create()
Filho.prototype = Object.create(Pai.prototype)
Faz herança prototipada
constructor
Filho.prototype.constructor = Filho
Corrige a referência do construtor
extends
class Filho extends Pai {}
Herança com classes (ES6)
super()
super()
Chama o construtor da superclasse
get/set
get nome() {}
Criam propriedades especiais
prototype
Classe.prototype.metodo = ...
Define métodos herdáveis
📚 Herança é uma ferramenta poderosa, mas deve ser usada com cuidado e propósito. Aprender como o JavaScript lida com isso te transforma num programador ou programadora muito mais preparado(a)! 🚀
Atualizado


