Da trilha de JavaScript Este conceito ainda não saiu como card do dia. ir para o card de hoje

JavaScript POO Intermediário

Protótipos

Em JavaScript, herança funciona através de protótipos: todo objeto tem uma referência interna a outro objeto, chamado de seu protótipo. Quando você acessa uma propriedade que não existe no objeto, o motor JS sobe pela cadeia de protótipos até encontrá-la ou chegar a null. Isso é diferente de linguagens baseadas em classes: aqui, objetos herdam diretamente de outros objetos.

A função Object.create(proto) cria um novo objeto cujo protótipo é proto, permitindo montar cadeias de herança de forma explícita. Já Object.getPrototypeOf(obj) lê o protótipo, enquanto obj.__proto__ é uma forma legada (e desencorajada) de acessá-lo. A propriedade prototype só existe em funções construtoras e é usada para definir o protótipo dos objetos criados com new.

Entender a diferença entre __proto__ (protótipo do objeto) e .prototype (protótipo dos futuros objetos criados por uma função) evita confusões comuns. Com Object.create, você pode implementar herança prototípica sem classes, controlando manualmente o encadeamento.

Pontos-chave

  • A cadeia de protótipos é a busca de uma propriedade subindo de objeto em objeto até null.
  • Object.create(proto) cria um objeto cujo protótipo interno é proto.
  • obj.__proto__ e Object.getPrototypeOf(obj) acessam o protótipo do objeto; .prototype é uma propriedade de funções.
  • Herança prototípica permite que objetos compartilhem métodos sem duplicá-los.
  • Sobrescrever um método no objeto filho não altera o protótipo, apenas cria uma propriedade própria.
prototipos.js
// Objeto base (protótipo)
const animal = {
  falar() {
    return `${this.nome} faz um som.`;
  }
};

// Cria um objeto cujo protótipo é 'animal'
const cachorro = Object.create(animal);
cachorro.nome = 'Rex';
cachorro.falar = function() {
  return `${this.nome} late.`;
};

// Cria outro objeto herdando de 'animal'
const gato = Object.create(animal);
gato.nome = 'Mimi';

console.log(cachorro.falar()); // Rex late. (método próprio)
console.log(gato.falar());     // Mimi faz um som. (herdado)

// Verificando a cadeia de protótipos
console.log(Object.getPrototypeOf(cachorro) === animal); // true
console.log(Object.getPrototypeOf(animal) === Object.prototype); // true
console.log(Object.getPrototypeOf(Object.prototype)); // null

// Usando função construtora e prototype
function Pessoa(nome) {
  this.nome = nome;
}
Pessoa.prototype.apresentar = function() {
  return `Olá, eu sou ${this.nome}`;
};

const joao = new Pessoa('João');
console.log(joao.apresentar()); // Olá, eu sou João
console.log(Object.getPrototypeOf(joao) === Pessoa.prototype); // true

Exercícios

  1. 1
    Fácil

    Criando um objeto com protótipo

    Use Object.create para criar um objeto carro que herda de veiculo. O objeto veiculo deve ter um método descrever() que retorna "Veículo genérico". O carro deve ter uma propriedade modelo e sobrescrever descrever() para retornar "Carro: <modelo>". Imprima o resultado de carro.descrever() e verifique se Object.getPrototypeOf(carro) === veiculo.

    Resolver
  2. 2
    Médio

    Cadeia de protótipos com função construtora

    Crie uma função construtora Animal que recebe nome e define this.nome. No Animal.prototype, adicione o método falar() que retorna "<nome> faz um som". Crie uma função construtora Cachorro que herda de Animal usando Object.create(Animal.prototype), e no Cachorro.prototype sobrescreva falar() para retornar "<nome> late". Crie uma instância rex = new Cachorro('Rex') e imprima rex.falar() e rex instanceof Animal.

    Resolver
  3. 3
    Desafio

    Cadeia de protótipos com Object.create e verificação

    Crie uma cadeia de três objetos: a, b e c, onde b herda de a e c herda de b. O objeto a deve ter a propriedade x = 1 e o método somar(y) que retorna this.x + y. O objeto b deve ter a propriedade x = 2. O objeto c deve ter a propriedade x = 3. Imprima c.somar(10), b.somar(10) e a.somar(10). Depois, use Object.getPrototypeOf para imprimir se o protótipo de c é b e se o protótipo de b é a. Por fim, delete a propriedade x de c e imprima c.somar(10) novamente.

    Resolver

Continue estudando