Protótipos e herança em JavaScript

Protótipos e herança em JavaScript
A herança é um conceito da programação orientada a objetos, embora o JavaScript apóie totalmente a herança entre pais e filhos, o trabalho está longe da programação tradicional orientada a objetos, isto é porque tudo em JavaScript é mapeado no construtor primitivo Objeto (Objeto com um capital O) é por isso que também é conhecido como o objeto mestre. Não interprete mal esse objeto mestre com o objeto Datatype.

JavaScript é frequentemente mal interpretado como um Olinguagem orientada a objeto, mas na realidade, isso não é verdade; JavaScript é uma linguagem baseada em protótipo. A herança em JavaScript é alcançada por algo chamado Herança prototípica. Para entender isso, primeiro precisamos estar familiarizados com a forma como um construtor funciona em javascript, como um objeto é criado contra um construtor e o que é o encadeamento de protótipo.

Este é um dos tópicos avançados do JavaScript e vamos levar você muito devagar e tentar explicar todas as informações junto com trechos, vamos começar.

Como um construtor funciona em JavaScript

Convencionalmente, construtores são funções especiais que são executadas toda vez que um objeto é criado contra uma classe; em javascript, toda expressão de funções é um construtor. Agora, se você vem de uma linguagem de programação trivial e tem algum plano de fundo com programação orientada a objetos, então você ficará confuso. Portanto, tente não comparar conceitos de JavaScript com programação trivial orientada a objetos.

Embora com a chegada da versão ES 6 do JavaScript, a palavra -chave “Aula”Foi adicionado ao JavaScript, mas isso não é usado para implementar o conceito de herança. No JavaScript, você pode criar objetos mapeados na função, sim - funções.

Imagine uma função criada com o seguinte código:

var pessoa = function ()

Como mencionado acima, que toda expressão de funções é um construtor, isso pode ser comprovado usando as seguintes linhas dentro da função:

var pessoa = função (nome)
esse.nome = nome;
esse.idade = 20

Agora, como você pode ver, estamos criando uma função e dentro do corpo da função, estamos definindo e inicializando propriedades do objeto, assim como fazemos em qualquer construtor convencional normal. Agora, vamos criar alguns objetos mapeados para isso Pessoas Função do construtor com as seguintes linhas de código:

var p1 = nova pessoa ("John");
var p2 = nova pessoa ("Albert");

Agora, estamos criando objetos, mas não temos um método dentro de objetos que nos devolvam o nome da pessoa que acabamos de criar, então vamos criar essa função dentro do construtor do Pessoa objeto.

var pessoa = função (nome)
esse.nome = nome;
esse.idade = 20;
esse.getName = function ()
retornar (isso.nome)

Agora, precisamos chamar essa função de cada objeto individual usando as seguintes linhas de código:

console.log (p1.getName ());
console.log (P2.getName ());

Depois de executar todo esse trecho, obtemos a seguinte saída no console:

Agora, aqui está o principal problema de usar esse tipo de modelo, imagine que você tem 100 objetos de Pessoa, Esses 100 objetos terão seus ter 100 diferentes GetName() funções:

Isso ocorre porque esses objetos são os casos do Pessoa, tornando -o redundante na memória. É aqui que o Propriedade do protótipo entra em jogo.

A propriedade do protótipo

Todas as funções e todos os objetos têm uma propriedade chamada Protótipo, Este protótipo contém métodos e propriedades de uma função, e essa propriedade do protótipo é compartilhada entre todas as instâncias/objetos que são mapeados para a função, dê uma olhada neste snippet:

Se criássemos alguns objetos com base nessa função “x”, Eles herdariam os métodos e propriedades dentro do“protótipo”Da função. Em nosso exemplo, a principal função seria o Pessoa e os objetos são P1, P2, como:

Usando a propriedade Prototype para criar herança prototípica

Nosso principal problema com a abordagem trivial era que todo objeto tinha seu próprio GetName() funções, quanto mais os objetos, mais é o número de GetName() funções na memória. Para remover isso, escrevemos o função getName () Fora da expressão do construtor e dentro da propriedade Prototype usando a sintaxe:

objectName.protótipo.MethodName

Nosso código muda em:

var pessoa = função (nome)
esse.nome = nome;
esse.idade = 20;

pessoa.protótipo.getName = function ()
devolver isso.nome;

var p1 = nova pessoa ("John");
var p2 = nova pessoa ("Albert");
console.log (p1.getName ());
console.log (P2.getName ());

A saída é exatamente a mesma da última vez:

Mas a diferença desta vez é que, em vez de cada objeto, tendo seu próprio GetName() função, cada objeto está acessando o GetName() função em seus pais e usando essa função para executar a instrução dada a ele. Isso é chamado “Herança prototípica”Em JavaScript. Eventualmente, não tornando -o redundante na memória.

Objeto mestre

Tudo em JavaScript é essencialmente um objeto, isso significa que tudo em JavaScript é baseado em Objeto (com um capital O).

Para explicar isso, use as seguintes linhas de código e abra o console do navegador.

var demo = function ()

console.dir (demonstração);

Você está criando uma função com um construtor vazio e o console.dir() exibe os detalhes de Demo () Definição da função no console, você verá isso:

Expandir a pequena ponta de seta e examinar o __proto__ propriedade desta função, o __proto__ Propriedade nos diz sobre qual objeto essa função mapeada, você verá o seguinte:

Agora, vamos criar uma instância dessa função de demonstração e examinar seu __proto__ como:

var demo = function ()

Seja x = new Demo ();
console.dir (x);

Depois de executar este código, você deve ver a seguinte saída no console:

Expanda isso e examine o construtor no qual a instância "x" foi mapeada, você verá:

Significando esse objeto x tem a demonstração dos pais, e já sabemos que o Demoção da funçãoé mapeado no objeto JavaScript. Isso cria uma cadeia de prototipagem como:

O objeto "x”Pode acessar os métodos e propriedades do objeto mestre, criando assim uma cadeia de herança.

Se olharmos em nosso console pela última vez, podemos examinar que o objeto mestre tem esse método em sua propriedade de protótipo que é para sequenciar() como:

E chamamos essa propriedade no objeto “x”E na função demonstração que você criou como:

console.log (x.para sequenciar());
console.log (demonstração.para sequenciar());

Você obtém a saída como:

Você pode ver, tanto o objeto quanto a função foram capazes de acessar esse método, mesmo que não tenha sido definido dentro deles.

É assim que a herança funciona em JavaScript através de protótipos.

Conclusão

A herança em JavaScript é muito diferente da nossa definição convencional de herança na programação orientada a objetos. Em JavaScript, alcançamos a herança usando uma propriedade chamada protótipo. Você aprendeu como um construtor funciona em javascript, qual é o protótipo Propriedade, como tudo dentro de JavaScript é um objeto aprendendo sobre Objeto mestre. Além disso, você aprendeu sobre herança prototípica e encadeamento de protótipos, e foi capaz de acessar os métodos e propriedades do Objeto mestre usando o objeto que você criou.