Fazendo Javascript OO de forma fácil
Essa é uma dica valiosa para o pessoal que quer escrever um Javascript mais “bonito”.
Embora a linguagem (em sua essência) seja Orientada a Objetos, temos que admitir que ela foge um pouco do convencional através do estilo de escrita prototype. Quero dizer que, é possível utilizarmos conceitos como encapsulamento, herança, atributos e métodos públicos e privados, etc. Mas de uma maneira um pouco diferente se comparada a linguagens como Python ou PHP.
A linguagem é composta por alguns objetos muito utilizados no cotidiano, como os objetos Array, Math e String. Estes (e outros objetos de core) são instâncias do objeto Object, que você pode representar através da seguinte expressão:
var meuObjeto = { };typeof(meuObjeto); // objecttypeof(Math); // objectVocê encontrará uma forma (muito bacana por sinal) de construir objetos através de expressões como essas:
var fooBar = { init: function() { console.log("Posso funcionar como um inicializador!"); }, _private: function(tipo) { console.log("Testando chamada " + tipo + "."); }, eggs: function() { console.log("Eggs."); fooBar._private("interna"); }, spam: function(msg) { console.log("Spam: " + msg + "."); },}; fooBar.init(); // Posso funcionar como um inicializador!fooBar.eggs(); // Eggs. // Testando chamada internafooBar._private("externa"); // Testando chamada externafooBar.spam("Eggs and Spam"); // Spam: Eggs and SpamPode-se observar que é uma prática válida para organizar código através de namespaces.
Referência: Using Objects to organize your code
Já utilizei algumas vezes o modelo acima… mas devo dizer que sou adepto a uma outra forma de construirmos classes em Javascript:
var Pessoa = function() { console.log("Pessoa instanciada!");}; Pessoa(); // Pessoa instanciada!console.log(typeof(Pessoa)); // functionvar pessoa1 = new Pessoa(); // Pessoa instanciada!console.log(typeof(pessoa1)); // objectNo exemplo acima, podemos reparar que seguindo o comportamento normal de uma função, não há surpresas na execução da expressão Pessoa. Porém, quando adicionamos o operador new na frente, o Javascript cria uma instância do tipo Pessoa. Basicamente é como se a expressão function fosse “multiuso”, sendo útil para definir funções e classes.
O mais legal disso é que, como você já deve ter reparado, com o uso do new ganhamos de graça um constructor (ou inicializador, como preferir) em nossa classe Pessoa.
Referência: Introduction to Object-Oriented Javascript
Do constructor em diante, já me deparei com algumas vertentes de implementações do Javascript. Já encontrei algumas bem simples, outras um pouco mais complicadas… vou mostrar aqui a que eu acredito ser a mais usual. Não tenho propriedade para dizer se é o modo certo ou mais elegante, apenas é o modo que incorpora características de OOP que melhor me atendeu:
var Linguagem = function(nome, versao) { this.nome = nome; this.versao = versao;};Acima temos a construção da classe Linguagem. Em seu constructor aproveitamos para setar alguns atributos, como nome e versao, que são passados imediatamente na hora de instanciá-la.
Para criar um método para esta classe, vamos recorrer ao prototype do Javascript:
Linguagem.prototype.descricaoCompleta = function() { return this.nome + " vr. " + this.versao;};Resumidamente, estamos adicionando um método de instância na estrutura da classe. Fazemos isso adicionando uma função ao prototype da classe. Dessa forma o método terá acesso as propriedades do objeto na hora que for instanciado.
Se tentarmos executar a expressão Linguagem.descricaoCompleta, iremos nos deparar com um erro de método inexistente. Mas, se instanciarmos a classe veremos que o método está acessível:
var python = new Linguagem("Python", "2.7");console.log(python); // Linguagemconsole.log(python.descricaoCompleta()); // Python vr.2.7Acima utilizamos o conceito de métodos e atributos de instância. Através do modelo Object Literal podemos ter um comportamento parecido com o conceito de métodos de classe:
var Linguagem = function(nome, versao) { this.nome = nome; this.versao = versao; // Chamando um método que está fora do prototype da classe this.meuId = Linguagem.incId();}; // Adicionando uma propriedade através de Object LiteralLinguagem.id = 0;// Adicionando um método através de Object LiteralLinguagem.incId = function() { this.id++; return this.id;} var javascript = new Linguagem("Javascript", "1.5");console.log(javascript); // Linguagemconsole.log(javascript.meuId); // 1Esta forma de criar classes e objetos em Javascript é executada com muito sucesso na biblioteca RGraph.Referências: Javascript is Object Oriented ProgrammingPara entender como criar heranças com o prototype do Javascript, vamos primeiramente criar um tipo chamado Framework:
var Framework = function(nomeFramework, nome, versao) { this.nome = nome; this.versao = versao; this.nomeFramework = nomeFramework;};No caso acima, iremos sobrescrever o comportamento do constructor da classe Linguagem.
E é aqui que a mágica acontece… instanciamos o tipo Linguagem no prototype da classe Framework. Isto fará com que o tipo Framework possua todas as propriedades de Linguagem. Depois corrigimos o constructor, apontando ele novamente para Framework:
// Cria herança com LinguagemFramework.prototype = new Linguagem();// Corrige o ponteiro do constructor para Framework (está apontando para Linguagem)Framework.prototype.constructor = Framework;Vamos adicionar um método exclusivo da classe Framework:
Framework.prototype.feitoEm = function() { return this.nomeFramework + " é feito em " + this.nome;};Instanciamos algumas vezes a classe Framework, e teremos o comportamento esperado de uma herança:
var django = new Framework("Django", "Python", "2.7");console.log(django); // Frameworkconsole.log(django.descricaoCompleta()); // Python vr.2.7console.log(django.feitoEm()); // Django é feito em Python var jquery = new Framework("jQuery", "Javascript", "1.5");console.log(jquery); // Frameworkconsole.log(jquery.descricaoCompleta()); // jQuery vr.1.5console.log(jquery.feitoEm()); // jQuery é feito em JavascriptExistem algumas frameworks (como a Mootools) que facilitam a criação de classes e heranças em Javascript.
O exemplo completo está disponível para download em: http://github.com/kplaube/post-javascript-oop
Até a próxima…
Fonte: Blog Klaus Laube
0 comments:
Post a Comment