Sobes.tech
Middle

O que é herança prototípica em JavaScript?

sobes.tech IA

Resposta da IA

No JavaScript, os objetos herdam propriedades e métodos dos seus protótipos. O protótipo de cada objeto é outro objeto, cujas propriedades e métodos estão acessíveis através da cadeia de protótipos.

Ao aceder a uma propriedade de um objeto, o JavaScript primeiro procura diretamente no próprio objeto. Se a propriedade não for encontrada, a procura continua no protótipo desse objeto, depois no protótipo do protótipo, e assim por diante, até que a propriedade seja encontrada ou até atingir o final da cadeia (null).

A herança prototípica difere da herança clássica (como em Java ou C++), onde os objetos são criados a partir de classes que descrevem a sua estrutura e comportamento. Em JavaScript, as classes, que surgiram no ES6, são uma sintaxe açúcar sobre a herança prototípica.

Aspectos principais:

  • __proto__: Propriedade interna do objeto que faz referência ao seu protótipo.
  • prototype: Propriedade do construtor (função usada como construtor), que faz referência ao objeto que servirá de protótipo para as instâncias criadas.
  • Object.getPrototypeOf(obj): Forma padrão de obter o protótipo de um objeto.
  • Object.setPrototypeOf(obj, proto): Forma padrão de definir o protótipo de um objeto.

Exemplo:

// Função construtora
function Animal(name) {
  this.name = name;
}

// Adiciona método ao protótipo Animal
Animal.prototype.sayHello = function() {
  console.log(`Olá, meu nome é ${this.name}`);
};

// Cria uma instância
const dog = new Animal("Buddy");

// Chama método do protótipo
dog.sayHello(); // Saída: Olá, meu nome é Buddy

// O protótipo de dog é Animal.prototype
console.log(Object.getPrototypeOf(dog) === Animal.prototype); // true

// O protótipo de Animal.prototype é Object.prototype
console.log(Object.getPrototypeOf(Animal.prototype) === Object.prototype); // true

// O final da cadeia de protótipos é null
console.log(Object.getPrototypeOf(Object.prototype) === null); // true

Comparação com herança clássica (usando classes ES6):

class Animal {
  constructor(name) {
    this.name = name;
  }

  sayHello() {
    console.log(`Olá, meu nome é ${this.name}`);
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name); // Chama o construtor da classe pai
    this.breed = breed;
  }

  bark() {
    console.log("Woof!");
  }
}

const buddy = new Dog("Buddy", "Golden Retriever");
buddy.sayHello(); // Saída: Olá, meu nome é Buddy (herdado de Animal)
buddy.bark(); // Saída: Woof! (método de Dog)

// Classes em ES6 são açúcar sintático sobre protótipos
console.log(Object.getPrototypeOf(Dog) === Animal); // true (herança de classes)
console.log(Object.getPrototypeOf(Dog.prototype) === Animal.prototype); // true (herança de métodos via protótipos)
console.log(Object.getPrototypeOf(buddy) === Dog.prototype); // true (a instância herda do protótipo da classe)

A herança prototípica é uma conceito chave em JavaScript, cuja compreensão é essencial para trabalhar eficazmente com a linguagem.