Por definição, sabemos que uma linguagem orientada a objetos tem como característica principal o modelo de linguagem baseada em classes. Sabemos que JavaScript não é uma linguagem baseada em classes, mas sim, baseada em protótipos. Uma linguagem baseada em prototypes tem a noção de um objeto protótipo, usado como modelo para se obter as propriedades iniciais de um novo objeto.
Por exemplo:
let carros = { carro1: "Gol", carro2: "Uno" } console.log(carros.carro1); console.log(carros.hasOwnProperty("carro3")); //gol //false
O objeto carros possui duas propriedades: carro1 e carro2, e nenhum outro método.
E o hasOwnProperty? Vem do Objeto Protótipo.
Expandindo o objeto carros no console, vemos que existe uma propriedade __proto__. Expandindo a propriedade __proto__, vemos que o hasOwnProperty está lá!
Todos os objetos têm acesso ao Objeto Prototype. Eles não possuem as propriedades, mas têm acesso concedido às propriedades no protótipo.
A propriedade __proto__:
Ela aponta para o objeto que é usado como protótipo. Esta propriedade em cada objeto, permite acesso ao Object prototype!
Todo objeto, por padrão, possui essa propriedade, exceto quando o __proto__ é apontado para outro protótipo. Podemos também modificar esta propriedade, declarando explicitamente que ela deve se referir a outro protótipo. Os seguintes métodos são usados para conseguir isso:
Object.create():
function ObjetoPessoa(nome, idade){ let pessoa = Object.create(objetoConstrutor); pessoa.nome = nome; pessoa.idade = idade; return pessoa; } let objetoConstrutor = { falar: function(){ return "Olá"; } } let joao = ObjetoPessoa("João", 54); console.log(joao);
Observe o método falar na propriedade __proto__. O Object.create usa o argumento passado para ele para se tornar o protótipo.
Utilizando o new:
A propriedade __proto__ é direcionada ao protótipo de ObjetoPessoa, mas este é um objeto (par de chave e valor), portanto, ele também possui uma propriedade __proto__ que refere-se ao protótipo global Object. Esta técnica é chamada de PROTOTYPE CHAINING.
O New faz a mesma coisa que o Object.create(), apenas facilitando-o, pois faz algumas coisas automaticamente para você:
function ObjetoPessoa(nome, idade){ this.nome = nome; this.idade = idade; } ObjetoPessoa.prototype.falar = function(){ return "Olá!" } let joao = new ObjetoPessoa("João", 45);
CLASS:
O ECMAScript 2015 introduziu a palavra-chave class, fazendo com que o javaScript se pareça com uma linguagem OOP. Mas é apenas um enfeite sobre a técnica de prototipagem existente, pois ele continua utilizando protótipos em segundo plano, apenas fazendo com que o corpo externo do código se pareça com OOP. Vejamos:
class Pessoas { constructor(nome, idade, humor){ this.nome = nome; this.idade = idade; this.humor = humor; } cantar(){ return this.nome + " está cantando!"; } dancar(){ return this.nome + " está dançando!"; } } let joao = new Pessoas("João", 25, "bem humorado"); console.log(joao);
E esse seria o resultado no console:
Veja que a propriedade __proto__ faz referências ao protótipo Pessoas (que faz referência ao protótipo Object). Podemos ver que o construtor define os principais recursos, enquanto cantar() e dancar() são os protótipos.
O código acima, sem utilizar a palavra-chave class, seria:
function Pessoas(nome, idade, humor){ this.nome = nome; this.idade = idade; this.humor = humor; } Pessoas.prototype.cantar() = function{ return this.nome + " está cantando!"; } Pessoas.prototype.dancar() = function{ return this.nome + " está dançando!"; } let joao = new Pessoas("João", 25, "bem humorado");
Gostou deste artigo? Comente abaixo!
Referências: https://www.freecodecamp.org/news/how-javascript-implements-oop/