Desafio JavaScript

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

Enunciado

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.

Requisitos

  • Criar a com x = 1 e método somar.
  • Criar b com Object.create(a) e x = 2.
  • Criar c com Object.create(b) e x = 3.
  • Imprimir c.somar(10), b.somar(10), a.somar(10).
  • Verificar e imprimir se Object.getPrototypeOf(c) === b e Object.getPrototypeOf(b) === a.
  • Deletar x de c e imprimir c.somar(10) novamente.

Código inicial

// Crie a, b e c com Object.create

// Imprima os resultados

// Verifique protótipos

// Delete x de c e imprima de novo

Saída esperada

13
12
11
true
true
12
Ver dica

Object.create cria um novo objeto com o protótipo especificado. Ao deletar x de c, a busca por x sobe para b, que tem x = 2.

Mostrar solução
// Objeto base
const a = {
  x: 1,
  somar(y) {
    return this.x + y;
  }
};

// b herda de a
const b = Object.create(a);
b.x = 2;

// c herda de b
const c = Object.create(b);
c.x = 3;

console.log(c.somar(10)); // 3 + 10 = 13
console.log(b.somar(10)); // 2 + 10 = 12
console.log(a.somar(10)); // 1 + 10 = 11

console.log(Object.getPrototypeOf(c) === b); // true
console.log(Object.getPrototypeOf(b) === a); // true

delete c.x; // remove x próprio de c
console.log(c.somar(10)); // agora usa x de b = 2, então 12

Passo a passo

  1. a é um objeto literal com x e o método somar.
  2. b é criado com Object.create(a), então seu protótipo é a; adicionamos x = 2 como propriedade própria.
  3. c é criado com Object.create(b), então seu protótipo é b; adicionamos x = 3.
  4. c.somar(10) chama o método herdado de a, mas this é c, então usa c.x (3) e retorna 13.
  5. b.somar(10) usa b.x (2) e retorna 12; a.somar(10) usa a.x (1) e retorna 11.
  6. Verificamos os protótipos com Object.getPrototypeOf.
  7. delete c.x remove a propriedade própria de c; agora c.x resolve para b.x (2).
  8. c.somar(10) retorna 12, mostrando a busca na cadeia.

Por que funciona

A cadeia de protótipos é consultada quando uma propriedade não existe no objeto. somar está em a, então é encontrado após subir toda a cadeia. Já x é procurado primeiro no próprio objeto; ao deletar de c, a busca sobe para b. Isso demonstra como a herança prototípica é dinâmica e baseada em delegação.

Erros comuns

  • Criar b e c sem Object.create — não haverá herança, e somar não será encontrado.
  • Esquecer que this dentro de somar refere-se ao objeto que chamou o método, não ao protótipo.
  • Usar c.__proto__ = b em vez de Object.create — funciona, mas __proto__ é obsoleto e menos seguro.
  • Deletar x de c e esperar que c fique sem x — na verdade herda de b.

Outra forma de resolver

Usar Object.setPrototypeOf(c, b) após criar c = { x: 3 }. Porém, Object.create é preferível por ser mais eficiente e claro. Também poderia usar classes, mas a herança prototípica explícita é o foco aqui.

Saída esperada

13
12
11
true
true
12