Criar classes em javascript – usando a Prototype

Orientação a objetos no javascript? É possível, sim. E muito necessário, ainda mais quando lidamos com projetos de grande porte.
Okey, javascript não é uma linguagem OO (abreviação para orientação a objetos). Nem tudo da orientação a objetos em javascript é possível ser implementada; alguns dos (famosos) paradigmas da OO são impossíveis de serem atingidos por limitações técnicas (por exemplo, não existe o conceito de interface, ou métodos que possam ser sobreescritos). O que não inviabiliza o uso da OO no javascript.

Se você não conhece muito de orientação a objetos, sugiro que você procure na web ou na literatura apropriada os conceitos. Esse post falará sobre o uso da (biblioteca) Prototype na ajuda a implementar a OO.

Quem já implementou do zero uma classe em javascript sabe que a dificuldade não é grande, mas que a sintaxe é meio estranha. Por exemplo, vamos criar uma classe que abstrai um objeto Pessoa:
[update]exemplo retirado do blog do Rodrigo, nesse post aqui[/update]

<script language="javascript">
function Pessoa() {
    var nome;
    var idade;
    var email;
    this.getNome = getNome;
    this.getIdade = getIdade;
    this.getEmail = getEmail;
    this.setNome = setNome;
    this.setIdade = setIdade;
    this.setEmail = setEmail;
    this.mostraValores = mostraValores;
    function getNome() {
        return nome;
    }
    function getIdade() {
        return idade;
    }
    function getEmail() {
        return email;
    }
    function setNome(_nome) {
        nome = _nome;
    }
    function setIdade(_idade) {
        idade = _idade;
    }
    function setEmail(_email) {
        email = _email;
    }
    function mostraValores() {
        return ´Nome: ´ + nome +´ Idade: ´+ idade +´ anos Email: ´+ email;
    }
}
</script>

Para consumir essa classe:

<script language="javascript">
    var pessoa = new Pessoa();
    pessoa.setNome("Rodrigo Lazoti");
    pessoa.setIdade(26);
    pessoa.setEmail("[email protected]");
    alert(pessoa.mostraValores());
</script>

Veja que essa classe mais parece um monte de codificação estruturada agrupada, nem não há um construtor para ela.

Vou direto para a codificação de como ficaria tal classe usando a Prototype:

referenciando a prototype:

<script src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.2/prototype.js" type="text/javascript"/>
var Pessoa = Class.create();
Pessoa.prototype = {
    //construtor padrão
    initialize: function(nome, idade, email) {
        this.setNome(nome);
        this.setIdade(idade);
        this.setEmail(email);
    },
    setNome: function(nome) {
        this.nome = nome;
    },
    setIdade: function(idade) {
        this.idade = idade;
    },
    setEmail: function(email) {
        this.email = email;
    },
    mostraValores: function() {
        return "Nome: " + this.nome + " Idade: "+ this.idade + " anos - Email: "+ this.email;
    }
}

Quem está acostumado com OO percebe logo de cara que, dessa forma, a semântica usada é muito mais direta e clara; você sempre se refencia aos atributos da classe usando this, e você sempre é obrigado a ter um método initialize que funciona como o construtor.
Para esclarecer o código, na primeira linha é usado um objeto Class da própria prototype e chama-se o seu método create(); a partir do retorno desse método tem-se um objeto que pode ser trabalhado como uma classe da Prorotype. Vale a pena lembrar que o código usado para consumir a classe pode ser exatamente o mesmo enquanto a interface (resumidamente, assinatura dos métodos) das mesmas forem iguais.

Agora, uma coisa bacana (peguei o exemplo lá na API da Prototype) é como extender uma classe. Imagine que você quer criar a partir da classe Pessoa, uma classe Pirata; digamos que o seu Pirata é do passado, e não tem e-mail. Mas tem um navio.
O primeiro passo é extender a classe Pessoa, da seguinte forma:

var Pirata = Class.create(Pessoa, {});

Vamos ver como ficaria o código para sobreescrever o método setEmail() e adicionar um método novo:

var Pirata = Class.create(Pessoa, {
    // sobreescreve o método que define o e-mail
    setEmail: function() {
        this.email = null;
    },
    //cria um método para salvar o nome do navio dele
    setNavio: function(navio) {
        this.navio = navio;
    }
   
});

Sugiro para quem está afim de estudar mais, primeiro olhar a documentação da API da Prototype e procurar exemplos por ae na net, e depois pegar algo que você já fez e funciona e tentar reescrever, do zero, usando orientação a objetos. É uma curva de aprendizado não muito complexa, mas é uma forma bem diferente de se programar para quem não está acostumado!

[update]e é claro que eu esqueci apenas de de falar que é necessário incluir a biblioteca prototype no seu javascript. Você pode fazer download ou referenciar a mesma que é hospedada pelo Google Code[/update]

Ajax Libraries API

Mais uma vez, está lá o Google oferecendo serviços para facilitar a vida dos desenvolvedores.

Dessa vez, lançaram um serviço no qual hospedam algumas famosas bibliotecas javascript no servidor e que você pode usá-las de lá. Nesse momento, as bibliotecas disponíveis são: jQuery, prototype, script.aculo.us, MooTools e Dojo.



A forma de se utilizar é simples: primeiro você referencia a biblioteca javascript do Google:

<script src="http://www.google.com/jsapi"></script>

Depois, você precisa (1) carregar a biblioteca quer utilizar e, (2) dentro da função de callback dela, poderá utilizar a sua biblioteca normalmente, como se tivesse carregado da forma tradicional.

No exemplo abaixo, eu criei uma página que usa as bibliotecas prototype e script.aculo.us e faz uma div ser arrastável pela tela – um exemplo simples de como começar o uso da AJAX Libraries API do Google:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Ajax Libraries API</title>
<script src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
	//1 - carrega bibliotecas prototype e scriptaculous
	google.load("prototype", "1.6");
	google.load("scriptaculous", "1.8.1");
	//2 - na função de callback, crio uma div que pode ser arrastada usando um objeto da script.aculo.us
	google.setOnLoadCallback(function() {
		new Draggable($("drag"));
	});
</script>
<style type="text/css">
	div#drag {
		width:100px; height:50px; cursor:pointer; border:1px solid #FF0000;
	}
</style>
</head>
<body>
<div id="drag">drag me</div>
</body>
</html>

 

Qual a vantagem?

Você não precisa se preocupar em estar sempre com a última versão de cada biblioteca – o Google hospedará sempre a última versão estável, e caso você não especifique qual você quer usar, ele disponibilizará essa -, terá sempre acesso às últimas (e mais bacanas) bibliotecas javascript que estão disponíveis na web e não precisar se preocupar em setar cabeçalhos de cachê, entre outras vantagens.

No site do AJAX Libraries API, há explicações de como carregar todas as bibliotecas, e referências mais específicas. Vale a pena 🙂

Fonte: http://googlesystem.blogspot.com/2008/05/google-hosts-popular-javascript.html