Resumo : neste tutorial, você aprenderá como funciona a herança prototípica do JavaScript.
Introdução à herança prototípica de JavaScript
Se você já trabalhou com outras linguagens de programação orientadas a objetos, como Java ou C++, está familiarizado com o conceito de herança.
Neste paradigma de programação, uma classe é um modelo para a criação de objetos. Se quiser que uma nova classe reutilize a funcionalidade de uma classe existente, você poderá criar uma nova classe que estenda a classe existente. Isso é chamado de herança clássica .
JavaScript não usa herança clássica . Em vez disso, ele usa herança prototípica .
Na herança prototípica, um objeto “herda” propriedades de outro objeto por meio da ligação de protótipo .
Herança prototípica de JavaScript e __proto__
Vamos dar um exemplo para deixar o conceito claro.
O seguinte define um person
objeto:
let person = {
name: "John Doe",
greet: function () {
return "Hi, I'm " + this.name;
}
};
Linguagem de código: JavaScript ( javascript )
Neste exemplo, o person
objeto possui uma propriedade e um método:
name
é uma propriedade que armazena o nome da pessoa.greet
é um método que retorna uma saudação como uma string.
Por padrão, o mecanismo JavaScript fornece uma função integrada Object()
e um objeto anônimo que pode ser referenciado por Object.prototype
:
Observe que o círculo representa uma função enquanto o quadrado representa um objeto.
O objeto person possui um link para o objeto anônimo referenciado pela Object()
função. O [[Prototype]]
representa a ligação:
Isso significa que o person
objeto pode chamar qualquer método definido no objeto anônimo referenciado pelo Object.prototype
.
Por exemplo, o seguinte mostra como chamar o toString()
método através do person
objeto:
console.log(person.toString());
Linguagem de código: JavaScript ( javascript )
Saída:
[object Object]
Linguagem de código: JavaScript ( javascript )
A [object Object]
é a representação de string padrão de um objeto.
Quando você chama toString()
o método via person
, o mecanismo JavaScript não consegue encontrá-lo no person
objeto. Portanto, ele segue a cadeia de protótipos e busca o método no Object.prototype
objeto.
Como o mecanismo JavaScript pode encontrar o toString()
método no Object.prototype
objeto, ele executa o toString()
método.
Para acessar o protótipo do person
objeto, você pode usar a __proto__
propriedade da seguinte forma
console.log(person.__proto__);
Linguagem de código: JavaScript ( javascript )
Observe que você nunca deve usar a __proto__
propriedade no código de produção. Por favor, use-o apenas para fins de demonstração.
O seguinte mostra person.__proto__
e Object.prototype
faz referência ao mesmo objeto:
console.log(person.__proto__ === Object.prototype); // true
Linguagem de código: JavaScript ( javascript )
O seguinte define o teacher
objeto que possui o teach()
método:
let teacher = {
teach: function (subject) {
return "I can teach " + subject;
}
};
Linguagem de código: JavaScript ( javascript )
Assim como o person
objeto, as teacher.__proto__
referências são Object.prototype
conforme ilustrado na imagem a seguir:
Se você deseja que o teacher
objeto acesse todos os métodos e propriedades do person
objeto, você pode definir o protótipo do teacher
objeto para o person
objeto assim:
teacher.__proto__ = person;
Linguagem de código: JavaScript ( javascript )
Agora, o teacher
objeto pode acessar a name
propriedade e greet()
o método do person
objeto por meio da cadeia de protótipos:
console.log(teacher.name);
console.log(teacher.greet());
Linguagem de código: JavaScript ( javascript )
Saída:
John Doe
Hi, I'm John Doe
Linguagem de código: JavaScript ( javascript )
Quando você chama o greet()
método no teacher
objeto, o mecanismo JavaScript o encontra primeiro no teacher
objeto.
Como o mecanismo JavaScript não consegue encontrar o método no teacher
objeto, ele segue a cadeia de protótipos e procura o método no person
objeto. Como o mecanismo JavaScript pode encontrar o greet()
método no person
objeto, ele executa o método.
Em JavaScript, dizemos que o teacher
objeto herda os métodos e propriedades do person
objeto. Esse tipo de herança é chamado de herança prototípica .
Uma maneira padrão de implementar herança prototípica no ES5
ES5 forneceu uma maneira padrão de trabalhar com herança prototípica usando o Object.create()
método.
Observe que agora você deve usar o ES6 mais recente class
e extends
palavras-chave para implementar herança . É muito mais simples.
O Object.create()
método cria um novo objeto e usa um objeto existente como protótipo do novo objeto:
Object.create(proto, [propertiesObject])
Linguagem de código: JavaScript ( javascript )
O Object.create()
método aceita dois argumentos:
- O primeiro argumento (
proto
) é um objeto usado como protótipo para o novo objeto. - O segundo argumento (
propertiesObject
), se fornecido, é um objeto opcional que define propriedades adicionais para o novo objeto.
Suponha que você tenha um person
objeto:
let person = {
name: "John Doe",
greet: function () {
return "Hi, I'm " + this.name;
}
};
Linguagem de código: JavaScript ( javascript )
O seguinte cria um teacher
objeto vazio com o __proto__
do person
objeto:
let teacher = Object.create(person);
Linguagem de código: JavaScript ( javascript )
Depois disso, você pode definir propriedades para o teacher
objeto:
teacher.name = 'Jane Doe';
teacher.teach = function (subject) {
return "I can teach " + subject;
}
Linguagem de código: JavaScript ( javascript )
Ou você pode executar todas essas etapas em uma instrução da seguinte maneira:
let teacher = Object.create(person, {
name: { value: 'John Doe' } ,
teach: { value: function(subject) {
return "I can teach " + subject;
}}
});
Linguagem de código: JavaScript ( javascript )
ES5 também introduziu o Object.getPrototypeOf()
método que retorna o protótipo de um objeto. Por exemplo:
console.log(Object.getPrototypeOf(teacher) === person);
Linguagem de código: JavaScript ( javascript )
Saída:
true
Linguagem de código: JavaScript ( javascript )
Resumo
- A herança permite que um objeto use as propriedades e métodos de outro objeto sem duplicar o código.
- JavaScript usa a herança prototípica.