Uma classe estendendo outra
A herança em JavaScript permite que uma classe parta do modelo de outra e vá além. Você herda todos os campos e métodos da classe pai de graça, e pode acrescentar ou alterar o que fizer sentido:
Dog extends Animal quer dizer: "um Dog é um Animal, com um pouquinho a mais". O rex não tem um método speak próprio, mas a busca sobe até Animal, que tem. Essa subida na cadeia é o mecanismo inteiro — no fundo é só encadeamento de protótipos com uma sintaxe mais agradável.
super no construtor de uma subclasse
Toda subclasse que tem construtor próprio precisa seguir uma regra inegociável: chamar super(...) antes de mexer em this. O super executa o construtor da classe pai, que é quem de fato cria e inicializa o objeto:
Se você pular a linha super(name), vai tomar um ReferenceError na hora que tentar ler ou escrever em this. O motor JavaScript simplesmente se recusa a te entregar um this antes de a classe pai fazer a parte dela.
Quando uma subclasse não declara o próprio construtor, o JavaScript cria um automaticamente que repassa todos os argumentos para super — ou seja, você só precisa escrever um quando for adicionar campos ou fazer alguma configuração extra.
Sobrescrever método em JavaScript
Uma subclasse pode redefinir qualquer método que herdou. Vence sempre o mais próximo na cadeia de protótipos:
Nada de mágica aqui: quando você chama speak() em um Dog, o motor procura speak na instância, depois em Dog.prototype, encontra lá e para. Ele nunca chega em Animal.prototype.
Estendendo em vez de substituir: super.method()
Às vezes você não quer substituir o método do pai — quer complementá-lo. O super.method(...) chama a versão do pai de dentro do método sobrescrito:
É aqui que a herança em javascript realmente se paga: a subclasse reaproveita a lógica da classe pai em vez de duplicá-la. Se Animal.describe mudar depois, Dog.describe já recebe essa mudança de brinde.
O super funciona em qualquer método, não só no construtor. Ele sempre aponta para a versão da classe pai daquilo que você está chamando.
instanceof e a cadeia de protótipos
O instanceof verifica se a cadeia de protótipos de um objeto inclui uma determinada classe. Toda instância de uma subclasse também é instância das suas classes pai:
Todos os quatro retornam true. A cadeia é Puppy -> Dog -> Animal -> Object, e o instanceof percorre ela inteira. É útil para verificar tipos, embora na prática você vá usar menos do que imagina — geralmente o código só chama métodos e deixa o polimorfismo cuidar do resto.
Um exemplo um pouco maior
Um padrão bem comum: uma classe base com a lógica compartilhada e algumas subclasses que a especializam.
Repare que describe vive em Shape e nunca precisa ser reescrito — ele só chama this.area(), que resolve para a subclasse correta em tempo de execução. Isso é polimorfismo: o mesmo ponto de chamada, comportamentos diferentes dependendo do objeto real.
Herança vs composição em JavaScript
A herança é tentadora porque parece produtiva — uma linha só e você ganha um monte de métodos de brinde. Só que ela envelhece mal quando a hierarquia cresce.
Regra prática: use extends quando a relação for claramente do tipo "X é um Y" e a subclasse realmente compartilhar a maior parte do comportamento da classe pai. Se você está apelando para herança só para reaproveitar um ou outro método auxiliar, prefira composição — dê à classe um campo que guarde o objeto auxiliar:
Árvores de herança profundas (Animal -> Mammal -> Dog -> WorkingDog -> PoliceDog) ficam lindas num diagrama e viram uma dor de cabeça no código — uma mudança perto da raiz se propaga de forma imprevisível para todos os descendentes. A maioria das bases de código saudáveis fica em um ou dois níveis de profundidade e resolve o resto com composição.
A seguir: membros estáticos
Tudo que vimos neste documento vive nas instâncias — métodos que você chama via new Coisa().alguma(). Só que, às vezes, você quer métodos ou dados que pertencem à própria classe, e não a uma instância específica. É exatamente para isso que serve o static, e é o nosso próximo assunto.
Perguntas frequentes
Como funciona herança em JavaScript?
Uma classe pode herdar de outra usando extends. A subclasse recebe todos os métodos e campos da classe-pai, e pode adicionar novos ou sobrescrever os existentes. Por baixo dos panos, o JavaScript liga o prototype da subclasse ao prototype do pai, então a busca por métodos sobe nessa cadeia automaticamente.
O que o super faz em JavaScript?
super(...) chama o construtor da classe-pai — e você precisa chamá-lo antes de usar this dentro do construtor da subclasse. Já super.metodo(...) chama a versão do método definida no pai, o que permite estender o comportamento em vez de substituí-lo por completo.
É melhor usar herança ou composição em JavaScript?
Use herança quando existe de fato uma relação 'é um' e a subclasse compartilha a maior parte do comportamento do pai. Quando você só quer reaproveitar funcionalidade, prefira composição — objetos que contêm outros objetos. Hierarquias de classes muito profundas costumam envelhecer mal; na prática, a maioria dos projetos fica em um ou dois níveis.