JavaScript OOP: Uma introdução parte 2

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/