Herança de Protótipos - JavaScript

JavaScript suporta herança, permitindo que criemos novos tipos de objetos que, quando necessário, herdem funcionalidades de objetos já existentes. No entanto, é importante entender que a herança em JavaScript difere da herança em outras linguagens populares como Java, C++, e C#. Em JavaScript, a herança é uma herança de objetos (e não de classes ou tipos), também conhecida como herança de protótipos ou herança prototípica.

Para criar um objeto baseado em um protótipo, utilizamos a função Object.create(), à qual passamos o protótipo a ser herdado:

const person = {
    name: "", 
    age: 0,  
    print: function() { 
        console.log(`Name: ${this.name}  Age: ${this.age}`);
    }
};
 
const employee = Object.create(person);  // employee utiliza o protótipo do objeto person
 
// obter o protótipo
console.log(employee.__proto__);     // {name: "", age: 0, print: ƒ}
 
employee.name = "Tom";
employee.age = 39;
employee.print();    // Name: Tom  Age: 39

Neste caso, o objeto employee é criado com base no protótipo do objeto person, ou seja, employeeherda o protótipo de person. Graças a essa herança, employee possui todas as propriedades e métodos definidos no objeto person.

Adicionalmente, objetos podem definir suas próprias propriedades e métodos. Por exemplo:

const person = {
    name: "", 
    age: 0,  
    print: function() { 
        console.log(`Name: ${this.name}  Age: ${this.age}`);
    }
};
 
const employee = Object.create(person);
employee.name = "Tom";
employee.age = 39;
employee.company = "Google";  // nova propriedade
// novo método
employee.work = function() { 
    console.log(`${this.name} works at ${this.company}`);
}
employee.print();    // Name: Tom  Age: 39
employee.work();    // Tom works at Google

Neste caso, o objeto employee também define a propriedade company e o método work.

Quando necessário, podemos redefinir métodos herdados:

employee.print = function() { 
    console.log(`Name: ${this.name}  Age: ${this.age} Company: ${this.company}`);
}
employee.print();    // Name: Tom  Age: 39  Company: Google

Aqui, a função print é redefinida para também exibir a empresa do funcionário. Podemos estender a cadeia de herança ainda mais:

const person = {
    name: "", 
    age: 0,  
    print: function() { 
        console.log(`Name: ${this.name}  Age: ${this.age}`);
    }
};

const employee = Object.create(person);
employee.company = "";

// objeto manager herda o protótipo do objeto employee
const manager = Object.create(employee);
// redefinindo o método print
manager.print = function() { 
    console.log(`Name: ${this.name}  Age: ${this.age}\nManager at ${this.company}`);
}
manager.name = "Bob";
manager.age = 43;
manager.company = "Microsoft";
manager.print();    // Name: Bob  Age: 43  
                    // Manager at Microsoft

Assim, criamos uma cadeia de protótipos: person-employee-manager: employee herda o protótipo de person, e manager herda o protótipo de employee.

Chamada de Métodos do Protótipo Base

Às vezes, pode ser necessário invocar métodos definidos no protótipo. Isso pode ser útil para reduzir duplicação de código, especialmente quando o código do método redefinido repete a lógica do método no protótipo. Ao obter o protótipo de um objeto, podemos chamar seus métodos usando a função call():

employee.print = function() { 
    this.__proto__.print.call(this);    // chama a versão do método de person
    // Object.getPrototypeOf(this).print.call(this); // outra forma de chamar 
    console.log(`Company: ${this.company}`);
}
 
employee.print();   // Name: Tom  Age: 39
                    // Company: Google

Neste exemplo, no método print redefinido do tipo employee, chamamos através do protótipo a versão do método print de person.

Verificação de Herança de Protótipos e Object.isPrototypeOf()

Usamos o método Object.isPrototypeOf() para verificar se um objeto é protótipo de outro:

const person = {
    name: "",
    print: ()=>console.log("Name:", this.name)
};
const user = {
    name: "",
    print: ()=>console.log("Name:", this.name)
};
 
// o objeto employee herda o protótipo de person
const employee = Object.create(person);
 
console.log(person.isPrototypeOf(employee));    // true
console.log(user.isPrototypeOf(employee));      // false

Aqui, o objeto employee herda o protótipo de person, então a chamada person.isPrototypeOf(employee) retorna verdadeiro, enquanto que user não é um protótipo de employee, apesar de ter o mesmo conjunto de métodos e propriedades.

Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com