New Post

Rss

Showing posts with label Fazendo. Show all posts
Showing posts with label Fazendo. Show all posts
Saturday, June 4, 2011
no image

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); // object

Você 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 Spam

Pode-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)); // object

No 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.7

Acima 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 Programming

Para 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 Javascript

Existem 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