Olá pessoal, tudo certo?

Dando continuidade ao post javaScript - Prototype  { Parte 1 }onde escrevi uma introdução sobre prototype, agora veremos alguns exemplos de como adicionar métodos e propriedades em objetos já existentes. Veremos também como sobrescrever métodos. No post passado eu comecei dizendo que cheguei no assunto prototype quando estava estudando para a prova de certificação 70-480 da Microsoft, disse também que segundo o guia de estudos esse assunto não caia na prova, bom, após alguns feedback's de quem já fez a prova, gostaria de dizer para aqueles que estiverem se preparando para essa certificação que estude esse assunto sim :)

javascript_logo

Todos os exemplos desse post foram testados utilizando o console do Google Chrome versão 40.0.2214.93 m.

Inserindo métodos e propriedades em objetos já existentes

Vamos inciar já com um pequeno snippet, veja a Listagem 1:

[sourcecode language="javascript"]
//criando um construtor para um tipo pessoa
//por convenção, utiliza-se um caractere uppercase na criação de construtores
function Pessoa(nome, sobrenome, idade){
this.nome = nome;
this.sobrenome = sobrenome;
this.idade = idade;
}

//criando uma instância de Pessoa
var wennder = new Pessoa('Wennder', 'Santos', 23);
[/sourcecode]

Listage 1 - Criando um construtor para um tipo Pessoa e criando uma nova instância de Pessoa.

Nosso objeto pessoa está muito "travado", vamos dar um pouco de ação a ele. Suponhamos que o objeto wennder queira cumprimentar outras pessoas, como fazer isso? Veja na Listagem 2:

[sourcecode language="javascript"]
wennder.cumprimentar = function(){
alert("Olá");
}
[/sourcecode]

Listagem 2 - Adicionando um método a um Objeto já existente.

Nesse momento, se chamarmos o método cumprimentar no objeto wennder teremos um alerta na tela.

wennder.cumprimentar();

Bem simples, mas, iremos fazer melhor do que isso. Continuando com o mesmo exemplo, vamos criar um novo objeto do tipo Pessoa, conforme mostra a Listagem 3.

[sourcecode language="javascript"]
var fulano = new Pessoa('Fulano', 'da Silva', 21);
[/sourcecode]

Listagem 3 - Criando nova instância de Pessoa.

Criada nova instância de Pessoa, ao tentar chamar o método cumprimentar teremos como retorno o seguinte erro:

[caption id="attachment_1391" align="alignnone" width="1900"]Figura 1 - Uncaught TypeError: undefined is not a function Figura 1 - Uncaught TypeError: undefined is not a function[/caption]

Isso indica que o objeto fulano não tem acesso ao método cumprimentar criado no objeto wennder, fica simples de entender se imaginarmos que os dois estão lado a lado na prototype chain.

Para que todas as instâncias de Pessoa possuam o método cumprimentar, deveríamos ter criado esse método no objeto prototype de Pessoa, o que também é bem simples de se fazer. Para exemplificar, vamos adicionar ao prototype de Pessoa a habilidade de "falar seu nome completo". Veja a Listagem 4:

[sourcecode language="javascript"]
Pessoa.prototype.nomeCompleto = function(){
alert(this.nome + ' ' + this.sobrenome);
}
[/sourcecode]

 Listagem 4 - Adicionando método ao prototype de Pessoa.

Fácil de entender? Caso a resposta seja 'não', vamos relembrar:

  1. Prototype é um objeto;
  2. Eu consigo adicionar métodos e propriedades a objetos, até os já existentes;
  3. Herança no javascript é feita através do objeto prototype.

Bom, nesse momento, ambos objetos fulano e wennder possuem acesso ao método nomeCompleto(). 

Espera ae, mesmo as instâncias que já foram criadas possuem acesso ao método que acabei de criar? Sim!

Ao chamar o método nomeCompleto() você receberá um alerta com o nome completo da pessoa, seja em novas instâncias de Pessoa ou nas que já existem.

É possível também adicionar métodos aos prototypes de objetos nativos, por exemplo o String. Veja a Listagem 5:

[sourcecode language="javascript"]
String.prototype.contarLetra = function(letra){
var contador = 0;

for(var i = 0; i < this.length; i++){
if (this[i] == letra){
contador ++;
}
}
return contador;
}
[/sourcecode]

Listagem 5 - Criando um método no protoype de String.

O método contarLetra simplesmente retornará a quantidade de vezes que uma determinada letra, que deverá ser informada por parâmetro, aparece em uma string. Veja um exemplo de sua chamada e seu retorno na Listagem 6:

[sourcecode language="javascript"]
"Realizando um teste".contarLetra("e"); //3
}
[/sourcecode]

Listagem 6 - Executando o método contarLetra.

Imagine que, após ter implementado  o método contarLetra surja a necessidade de fazer com que esse método não diferencie letras minúsculas de maiúsculas. Para exemplificar o segundo ponto desse post, vamos resolver essa situação sobrescrevendo o método contarLetra .

 

Sobrescrever métodos

No javaScript, quando criamos dois métodos/propriedades com o mesmo nome nós não temos como retorno um erro. O que acontece é que a segunda declaração sobrescreverá a primeira. Simples assim. Veja o código da Listagem 7, onde estamos sobrescrevendo o método contarLetra.

[sourcecode language="javascript"]
String.prototype.contarLetra = function(letra){
var contador = 0;

for(var i = 0; i < this.length; i++){
if (this[i] == letra){
contador ++;
}
}
return contador;
}

//este método irá sobrepor o anterior
String.prototype.contarLetra = function(letra){
var contador = 0;
var palavraMaiuscula = this.toUpper;
var letraMaiuscula = letra.toUpper;

for(var i = 0; i < this.length; i++){
if (palavraMaiuscula[i] == letraMaiuscula){
contador ++;
}
}
return contador;
}

"REALIZANDO UM TESTE".contarLetra("e"); //3
"realizando um teste".contarLetra("E"); //3
[/sourcecode]

Listagem 7 - Sobrescrevendo o método contarLetra.

Na Listagem 7, foram declarados dois métodos contarLetra. A diferença entre os dois é que a primeira declaração diferencia letras maiúsculas de minúsculas. Ao declarar os dois métodos com o mesmo nome, como já dito anteriormente, não temos nenhum erro e sim uma sobreposição que pode ser vista na execução do mesmo. Ao executar o método contarLetra nesse momento, veremos que não está sendo mais diferenciado as letras maiúsculas de minúsculas.

Pessoal, era isso que eu queria mostrar nessa publicação.

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/