Herança em JavaScript é tudo protótipo

Todos nós sabemos que o JavaScript usa herança prototípica em vez do tipo clássico. Apesar de todos nós usarmos frameworks MVC avançados como AngularJs ou Ember.js, que fazem um ótimo uso da herança prototípica, ainda é fácil para nós ficarmos confusos sempre que alguém nos pede para explicar a herança em JavaScript.

O Mozilla tem um excelente guia sobre Herança e a cadeia de protótipos que é provavelmente o link para indicar alguém se fizer a temida pergunta … Quando se trata de herança, JavaScript só tem uma grande construção: objetos. Cada objeto possui um link interno para outro objeto denominado seu protótipo. Esse objeto de protótipo tem um protótipo próprio e assim por diante até que um objeto seja alcançado com null como seu protótipo, o elo final na cadeia de protótipo.

<b> Herdando propriedades e métodos em JavaScript </b>

Os objetos JavaScript são pacotes dinâmicos de propriedades e cada um tem um link para um objeto protótipo. Em JavaScript, qualquer função pode ser adicionada a um objeto na forma de uma propriedade e, nessa forma, é conhecida como método. Uma função herdada atua como qualquer outra propriedade. Quando uma função herdada é executada, o valor desta aponta para o objeto herdado.

<b> Criação de objetos que herdam propriedades </b>

Existem muitas abordagens para criar objetos que herdam de outros objetos em JavaScript, as abordagens mais comuns são usar a nova palavra-chave ou usar Object.create ()

<b> Construtor </b>

Um “construtor” em JavaScript é uma função chamada com o novo operador.

function Person(name) {
this.name = name;
}

Person.prototype.printName = function () {
console
.log(this.name);
}

var me = new Person("Steven");
me
.printName();

<b> Object.create () </b>

ECMAScript 5 introduziu Object.create. Chamar este método cria um novo objeto com o objeto de protótipo especificado e propriedades.

var a = { message: 'I am an a'}; 
var b = Object.create(a);
b
.message = 'I am now a b';

É essencial entender o modelo de herança prototípico antes de escrever um código complexo que faça uso dele. Também é interessante para nós entender por que realmente nos importamos com herança em primeiro lugar. De acordo com Crockford, existem duas razões principais.

<b> Digite conveniência </b>

Queremos que o sistema de linguagem lance automaticamente referências de classes semelhantes. Isso é importante em linguagens fortemente tipadas, mas é irrelevante em linguagens vagamente tipadas como JavaScript, onde as referências de objeto nunca precisam ser convertidas.

<b> Reutilização de código </b>

É comum ter um conjunto de objetos, todos implementando exatamente o mesmo método. As classes permitem criar esses objetos a partir de um único conjunto de definições. Também é comum ter objetos semelhantes diferindo apenas em alguns métodos. A herança clássica é útil para isso, no entanto, a herança prototípica também pode ser muito útil para isso.

Como mostramos, em JavaScript, os objetos são facilmente estendidos. Um novo membro pode ser adicionado a um objeto por simples atribuição. Como os objetos em JavaScript são muito flexíveis, é importante pensar de forma diferente sobre as hierarquias de classes. Hierarquias profundas são inadequadas. Hierarquias rasas são mais expressivas.

<b> Aulas em EcmaScript 6 </b>

EcmaScript 6 introduz suporte de linguagem para classes com <i> classes </i>, <i> construtores </i> e a palavra-chave <i> extend </i> para herança.

class Car {
constructor(make) {
this.make = make;
this.currentSpeed = 50;
}
}

class RaceCar extends Car {
constructor(make, topSpeed) {
super(make);
this.topSpeed = topSpeed;
}

goFast
(){
this.currentSpeed = this.topSpeed;
}
}

let corvette = new RaceCar('Corvette', 150);
corvette
.goFast();

O JavaScript é de natureza prototípica, portanto, a questão deve ser levantada: “Precisamos de herança clássica em JavaScript?” Não vou entrar em muitos detalhes aqui, Nicholas Zakas tem um excelente artigo sobre esse assunto. Como Nicholas menciona, a proposta de classe ECMAScript 6 atual é simplesmente uma nova sintaxe no topo dos padrões prototípicos atuais atualmente em uso comum em JavaScript. Herança funciona da mesma maneira que sempre, encadeamento de protótipo, métodos adicionados a protótipos e propriedades declaradas no construtor.