Olá pessoal, tudo bom?

Há algumas semanas atrás eu comecei a estudar para uma prova de certificação da Microsoft, a 70-480 Programming in HTML5 with JavaScript and CSS3, segundo o guia de estudo oficial, não é requerido o assunto desse post, mas acabei caindo nele em algumas pesquisas.

Ao começar os estudos no JavaScript achei interessante o assunto prototype, e resolvi escrever esse post. Então, let's go!

javascript_logo

Nos exemplos mostrados abaixo foi utilizado o console do Google Chrome versão 39.0.2171.99 para testa-los.

Antes de começarmos, caso não esteja familiarizado com objects, aconselho a seguinte leitura:

O que é prototype?

Prototype é um objeto que todos os objetos, por default, o possuem como propriedade e é partir dessa propriedade que trabalhamos com herança no javascript. Toda nova instância de um objeto herdará os comportamentos presentes na propriedade prototype definidas nesse objeto.

Vejamos um primeiro exemplo na Listagem 1.

[sourcecode language="javascript"]
var pessoa = {};
[/sourcecode]

Listagem 1 - Criando um novo objeto.

Reparem na Listagem 1, nenhum método ou propriedade foi adicionado a instância de Object pessoa. Entretanto, se analisarmos, veremos que essa instância já possui os seguintes métodos:

Esses métodos também podem ser vistos através da Figura 1, onde estou criando a instância de Object pessoa no console do Chrome.

[caption id="attachment_901" align="alignnone" width="1600"]Figura 1 - Métodos do objeto pessoa. Figura 1 - Métodos do objeto pessoa.[/caption]

Bom, se eu não criei esses métodos, quem os criou? Logo teremos essa resposta.

Ainda seguindo o exemplo da Listagem 1, criamos a instância de Object pessoa vazio (sem nenhum método ou propriedade) de uma forma denominada objetct literal notation. Como disse anteriormente, todo objeto possui uma propriedade chamada prototype que também é um objeto. Todo objeto prototype está diretamente ligado ao objeto prototype que está logo acima na prototype chain, dessa forma, herdando os métodos e propriedades de todos os objetos prototypes que estão acima de sua criação na prototype chain. Caso tenha ficado um pouco confuso, vamos ilustrar alguns exemplos de prototype chain.

Prototype chain

Para conseguirmos visualizar e entender de forma clara o que significa prototype chain, vamos relembrar o código da Listagem 1.

[sourcecode language="javascript"]
var pessoa = {};
[/sourcecode]

Nesse simples trecho de código, onde criamos uma instância de Object vazia chamada pessoa, podemos visualizar sua prototype chain da forma ilustrada na Figura 2.

[caption id="attachment_972" align="alignnone" width="391"] Figura 2 - Prototype chain, Object.prototype, Array.prototype.[/caption]

Como pessoa foi criado utilizando object literal notation, ele herda diretamente de Object.prototype. Vale frisar que, todo objeto, diretamente ou indiretamente herdará de Object.prototype, uma vez que Object.prototype está no topo da prototype chain.

Para deixar claro que todo objeto herdará de Object.prototype, veja na Listagem 2 a criação de um objeto utilizando um tipo pré-definido no javascript, o Array.

[sourcecode language="javascript"]
//eu poderia também ter criado da seguinte forma
//var arr = [];
//o resultado seria o mesmo
var arr = new Array();
[/sourcecode]

Listagem 2 - Criando um objeto do tipo Array.

O tipo Array, da mesma forma que Object, também possui métodos e propriedades pré-definidos em sua propriedade prototype. Os métodos e propriedades encontrados em Array.prototype são os seguintes:

Para visualizar os métodos de Array.prototype, faça o mesmo teste ilustrado na Figura 1. Ao realizar esse teste, você verá que a instância de Array arr possui métodos e propriedades herdados tanto de Array.prototype quanto de Objetc.prototype. Porque isso? prototype chain! Veja na Figura 3 uma nova ilustração de prototype chain dando continuidade a Figura 2.

[caption id="attachment_1081" align="alignnone" width="709"]Figura 3 - Protoype chain, Object.prototype, Array.prototype. Figura 3 - Protoype chain, Object.prototype, Array.prototype.[/caption]

Mais fácil entender quando se desenha? Espero que sim :)

Antes de finalizar essa primeira parte sobre prototypes, vamos entender mais um ponto.

Como já sabemos, a propriedade prototype é um objeto. Sabemos também que todo objeto possui uma propriedade prototype, certo? Se você se perguntou se a propriedade prototype também possui uma propriedade com esse nome, você raciocinou bem! Para ilustrar isso, vamos abrir o console do chrome e realizar alguns testes utilizando a propriedade __proto__conforme mostra a Listagem 3.

[sourcecode language="javascript"]
var arr = new Array();
//undefined
arr.__proto__
//[]
arr.__proto__.__proto__
//Object {}
arr.__proto__.__proto__.__proto__
//null
[/sourcecode]

 Listagem 3 - Navegando pela prototype chain

Analisando o código da Listagem 3, podemos ver que a propriedade __proto__ está nos retornando o objeto prototype da propriedade prototype que estamos acessando. No parágrafo que antecede esse, disse que todos os objetos possuem uma propriedade prototype, entretanto, existe uma exceção que pôde ser mostrada na Listagem 3, onde, ao tentarmos acessar o prototype de Object.prototype temos um retorno null. Com isso reforçamos que Object.prototype está no topo da prototype chain.

O mesmo acontece quando tentamos acessar uma propriedade que não existe em nenhum objeto da prototype chain, veja um exemplo na Listagem 4.

[sourcecode language="javascript"]

var arr = new Array();
//undefined
arr.teste
//undefined

[/sourcecode]

 Listagem 4 - Tentando acessar uma propriedade que não existe em nenhum objeto da prototype chain

Na Listagem 4, ao tentar acessar a propriedade teste, é percorrido toda a prototype chain tentando encontrá-lo em algum objeto prototype. Essa busca termina no mesmo momento onde temos o retorno null na Listagem 3 e nesse caso temos um retorno undefined.

Pessoal, era isso o que eu queria mostrar nessa primeira parte. No próximo artigo sobre prototype mostrarei como criar nossa própria cadeia de herança e como adicionar / sobrescrever métodos e propriedades já existentes em objetos.

Encontrou algum erro ou não concorda com algo? Deixe um comentário e vamos discutir isso para que todos possam acompanhar.

Até o próximo post!

 

Referências

Object.prototype - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype

Understanding JavaScript Prototypes - https://javascriptweblog.wordpress.com/2010/06/07/understanding-javascript-prototypes/

Gosta de javaScript mas não encontra bom conteúdo em pt-br? De uma olhada no site do Suissahttp://nomadev.com.br/