Vários desenvolvedores web falam que protótipos representam uma forma de definirmos tipos de objetos, mas se você observar com cuidado, isto é uma característica de funções.
Perceba que todas as funções têm uma propriedade prototype que, inicialmente, referencia um objeto vazio.
Usando a palavra chave New para invocar a função construtor, temos agora um objeto recém instanciado como seu contexto.
Ex:
O básico – Incluindo métodos numa classe (função)
Temos nossa classe Lutador, que se encontra vazia e queremos anexar um método a ela. Logo utilizamos a seguinte estrutura:
Um protótipo nos permite predefinir propriedades, incluindo métodoss. Você pode saber como acessar as propriedades de protótipos a partir da instância do objeto com lutador1.constructor.prototype.Socar.
Uma observação importante é que não importa a ordem onde o protótipo é declarado, pois “suas atualizações” são feitas dinamicamente, ex:
Isto:
Tem o mesmo sentido de:
Podemos também instânciar um objeto deste modo:
Note que lutador1 não é o mesmo objeto de lutador2, mas são duas instâncias distintas.
Tudo que vimos até agora, foi o básico de que os protótipos oferecem, agora está na hora de avançar um pouco mais.
Herança e a cadeia de protótipos
Existem várias formas de como obter uma herança com protótipos, mas sem dúvida, a melhor forma é este modo:
Nota: “Existe também outra técnica semelhante a esta, e que eu desaconselho. É utilizar o objeto do protótipo de Habilidades_ diretamente como protótipo de_ Lutador_… Ex:_ Lutador.prototype = Habilidades.prototype; pois fazendo isto, qualquer alteração no protótipo de Lutador também modificará o protótipo de Habilidades_, porque eles serão o mesmo objeto, e isso com certeza terá alguns efeitos colaterais indesejaveis_
Incluindo novo método nos elementos HTML por meio do protótipo HTMLElement
Nos navegadores atuais e antigos (IE8+) temos uma funcionalidade bastante interessante que nos permite estender qualquer nó HTML de nossa escolha, vejamos então o próximo exemplo:
Neste exemplo incluimos um novo método “remover”, em todos os elementos do DOM por meio do protótipo do contrutor HTMLElement. Logo depois removemos o elemento html que tem por _id=”a” _
Um exemplo muito bom de utilização deste recurso é a biblioteca Prototype, por ela conseguimos obter muitas funcionalidades nos elementos DOM, por exemplo injetar HTML e manipular CSS.
Extenção de Object e Array
Por meio de protótipos também podemos estender os tipos primitivos do javascript, como: Object, Array e Number. Vejamos como estender uma variável do tipo array por meio de protótipos:
Note que adicionamos um método “cataFruta()”, que serve como um forEach dentro do array, e este mesmo método pode receber um callback que retorna dois parâmetros, que é o elemento atual em execução e o seu índice. Também podemos estender Object:
Note que usamos a mesma lógica para os dois, só mudou que ao invés de Array.prototype colocamos Object.prototype. Também podemos estender o tipo Number, algo que não recomendo pois ele é um protótipo nativo muito problemático.
“Devido à forma como números e propriedades de números são processados pelo engine JavaScript, alguns resultados podem ser bastante confusos…” (Segredos do Ninja Javascript::Novatec)
Subclasse do objeto Array
Como expliquei mais à cima, existe um modo de herdamos heranças em classes JavaScript, isso não é diferente com o objeto Array. Vejamos um exemplo de como podemos criar uma subclasse do tipo array:
Um erro grave de usuário
Tudo que vimos até agora é muito bom e ajuda bastante para nossas aplicações JavaScript, com esse conhecimento e um pouco de esforço da até mesmo para criar sua própria biblioteca JavaScript. Mas ainda eu não poderia encerrar o artigo sem antes lhes prevenir de um erro que alguns usuários com pouco conhecimento de JavaScript cometem…
Tudo que vimos não terá utilidade nenhuma se não invocarmos a função como construtor. Imagine que um usuário leigo de JS pegou seu código mas tenta invocar a função “como função” achando que é assim que tem que ser feito. ex:
Note no console de seu navegador que um erro aconteceu ao tentarmos verificar o name de homem. Logo isto ocorrerá sempre que o usuário tentar invocar a “função como função”.
_Então qual será a solução para este problema? _
Simples podemos fazer uma verificação, se o objeto é uma instância da função… caso não seja, retornaremos a forma correta de como chamar a função e tudo estará resolvido. Ex:
Rode agora nosso script e veja que tudo vai bem, e não aparece erro nenhum no console 🙂
Bem vou parar por aqui para o artigo não ficar muito grande, por hoje é só, um forte abraço de Clóvis Neto e até a próxima 😀