Como já vimos na parte 1 da nossa Introdução a OOP, O JavaScript possui agora a palavra Class, que “mascara” o prototype que continua acontecendo por baixo dos panos. Ou seja, o JavaScript não é uma linguagem baseada em classes, mas sim, continua sendo baseada em protótipos.
Extends:
É um recurso da OOP, que uma classe herda recursos de outra classe pai, mas possui recursos extras que a classe pai não possui.
Por exemplo, a classe crianças pode ter propriedades extras, como quantidade de brinquedos.
Vamos ver:
class Criancas extends Pessoas { constructor(nome, idade, humor, qtdBrinquedos){ super(nome, idade, humor); this.qtdBrinquedos = qtdBrinquedos; } meusBrinquedos(){ return "Eu tenho " + this.qtdBrinquedos + " brinquedos!"; } } let dudu = new Criancas("Eduardo", 6, "Bem humorado", 12); console.log(dudu);
Com isso, vimos que, utilizando a palavra-chave extends, utilizamos propriedades existentes na classe pai (Pessoas), como nome, idade e humor. Mas também, a nossa classe Crianças possui um outro atributo, chamado qtdBrinquedos, que é exclusivo da classe Crianças, ou seja, não existe na classe pai (Pessoas). O resultado no nosso console é:
Pessoas { nome: 'João', idade: 25, humor: 'bem humorado' } Criancas { nome: 'Eduardo', idade: 6, humor: 'Bem humorado', qtdBrinquedos: 12 }
E podemos também utilizar os métodos da nossa classe pai. Por exemplo, podemos ver que nossa criança pode cantar, dançar e nos dizer quantos brinquedos possui:
console.log(dudu.cantar()); console.log(dudu.dancar()); console.log(dudu.meusBrinquedos()); //Eduardo está cantando! //Eduardo está dançando! //Eu tenho 12 brinquedos!
E se você mostrar o conteúdo da variável dudu no console, verá que possui uma propriedade __proto__ que faz referência ao construtor Crianças e também obtém acesso ao método meusBrinquedos(). Essa __proto__ também possui uma propriedade __proto__, que faz referência ao construtor Pessoas, obtendo acesso aos seus métodos: cantar() e dancar(). Nome, idade e humor são propriedades que existem em todos objetos que herdam as propriedades da classe Pessoas.
Usando o Object.create, o código se traduz em:
function Pessoas(nome, idade, humor){ let novaPessoa = Object.create(pessoaConstructor); novaPessoa.nome = nome; novaPessoa.idade = idade; novaPessoa.humor = humor; return novaPessoa; } let pessoaConstructor = { cantar: function(){ return this.nome + " está cantando!"; }, dancar: function(){ return this.nome + " está dançando!"; } } function Criancas(nome, idade, humor, qtdBrinquedos) { let novaCrianca = Pessoas(nome, idade, humor); Object.setPrototypeOf(novaCrianca, criancaConstructor); novaCrianca.qtdBrinquedos = qtdBrinquedos; return novaCrianca; } let criancaConstructor = { meusBrinquedos: function(){ return "Eu tenho " + this.qtdBrinquedos + " brinquedos!"; } } Object.setPrototypeOf(criancaConstructor, pessoaConstructor); const dudu = Criancas("Eduardo", 6, "bem humorado", 12); console.log(dudu.cantar()); console.log(dudu.dancar()); console.log(dudu.meusBrinquedos()); //Eduardo está cantando! //Eduardo está dançando! //Eu tenho 12 brinquedos!
O método Object.setPrototypeOf recebe dois argumentos:
- O objeto (primeiro argumento);
- O protótipo desejado (segundo argumento).
A função Pessoas retorna um objeto protótipo com o pessoaConstructor. A função Criancas retorna um objeto protótipo de criancaConstructor; criancaConstructor, por outro lado, é dadum um protótipo de pessoaConstructor.
Gostou deste artigo? Comente abaixo!
Referências: https://www.freecodecamp.org/news/how-javascript-implements-oop/