Me lembro que fiquei muito intrigado quando ouvi de um colega da área que sua linguagem de programação preferida atualmente era JavaScript. Esse camarada foi instrutor em uma conceituadíssima escola de desenvolvimento e, na ocasião em que nos falamos, era consultor sênior em uma grande empresa igualmente muito bem conceituada, logo, sabia do que estava falando, por isso fiquei mais intrigado ainda.
Na sequência dos acontecimentos, o destino me levou a parar em um projeto onde fiz uso intensivo de JavaScript. Bela coincidência!
Meus últimos projetos tinham sido em Java, o que me levou a me habituar com frameworks component-based como Primefaces para construir minhas telas, me concentrando mais no middleware e no backend. Em virtude disso, minha visão de JavaScript continuava sendo aquela de uma linguagem complicada, instável e não robusta. Mas nesse novo projeto comecei a assimilar melhor a ideia de que a linguagem ressurgira nos últimos anos com uma força gigante. Yahoo, GMail, Facebook, LinkedIn, entre tantos outros serviços da Web, faziam vasto uso de JS para o dinamismo e interatividade de suas funcionalidades.
Para um melhor rendimento e produtividade no novo projeto, busquei bons materiais sobre o assunto e os estudei a fundo, livros bons sobre JavaScript, jQuery, ExtJS, dentre outros, todos mencionados no final desse post. Minha visão ampliou e comecei a entender melhor o colega.
Haveria muito para escrever, mas neste post quero me concentrar em um tópico central que diz respeito às possíveis formas de se criar objetos em JS, definindo atributos, transportando-os entre as funcionalidades da aplicação, reaproveitando-os, enfim, fazendo o que se costuma fazer com objetos.
Anatomia de um objeto em JS
Um objeto em JS nada mais é do que um mapa de pares chave-valor, onde o valor pode ser um primitivo ou outro objeto (o que caracterizaria os fields do objeto) ou ainda uma função (o que caracterizaria suas funções/métodos).
var pessoa = { nome: "Daniel", sobrenome: "Adornes", nacionalidade: { nome: "Brasileiro", idioma: "Português" }, nascimento: "2000-01-01", // Obviamente fake idade: function(){ ... // Calcular idade pela data de nascimento ... } }; console.log(pessoa.nome); // Daniel console.log(pessoa.sobrenome); // Adornes console.log(pessoa.nacionalidade.idioma); // Português console.log(pessoa.idade()); // O cálculo retornaria 12
No exemplo acima, nome, sobrenome e nascimento são atributos simples, enquanto que nacionalidade é um outro objeto que também possui seus atributos e idade é uma função que calcula a idade a partir da data de nascimento.
As chaves também podem ser definidas como string, o que é mais comumente utilizado quando o nome foge ao que a linguagem permite para variáveis, por exemplo, "data_nascimento" poderia ser um chave válida no formato do exemplo anterior, porém "data-nascimento" teria que ser como string, assim o acesso seria feito como pessoa['data-nascimento'].
new Object()
Outra forma de criar objetos em JS é através de um new Object() e a adição posterior dos atributos/métodos desejados. É importante ressaltar que na abordagem anterior também é perfeitamente possível adicionar atributos após a criação do objeto.
var pessoa = new Object(); pessoa.nome = "Daniel"; pessoa.sobrenome = "Adornes"; pessoa.nacionalidade = { nome: "Brasileiro", idioma: "Português" }; pessoa.nascimento = "2000-01-01"; pessoa.idade = function(){ ... // Calcular idade pela data de nascimento ... }; ... ...
Função como objeto
Ainda outra forma de criar objetos em JS é através da definição de uma função que será o construtor do objeto:
var Pessoa = function(nome, sobrenome){ this.nome = nome; this.sobrenome = sobrenome; }; var daniel = new Pessoa('Daniel', 'Adornes'); var outraPessoa = new Pessoa('Outra', 'Pessoa'); console.log(daniel.constructor); // função construtora ... ...
Nesse exemplo, a função Pessoa desempenha o papel parecido com o construtor de uma classe (como na maioria das linguagens orientadas a objetos), porém o objeto instanciado fica livre da estrutura imposta por uma classe, justamente por não existir este conceito em JavaScript. Assim, o objeto instanciado pode ainda ser alterado de forma a receber novos atributos ou até mesmo perder atributos, conforme o exemplo abaixo:
// Definindo um novo atributo daniel.nascimento = '01/01/2000'; console.log(daniel.nascimento); // Removendo atributo delete daniel.nascimento; console.log(daniel.nascimento); // Retorna undefined ... ...
Protótipo
O conceito por trás dos exemplos anteriores é que em JavaScript os objetos não são baseados em classes, mas sim em protótipos. Toda função é um objeto e referencia um protótipo que, por padrão, é um objeto vazio (sem atributos ou funções). Este protótipo, no entanto, pode ser alterado de forma a disponibilizar métodos para quaisquer instâncias criadas a partir da função, antes ou depois da alteração do protótipo.
function Pessoa(nome, sobrenome){ this.nome = nome; this.sobrenome = sobrenome; }; var daniel = new Pessoa('Daniel', 'Adornes'); var outraPessoa = new Pessoa('Outra', 'Pessoa'); Pessoa.prototype.nomeCompleto = function(){ return this.nome + ' ' + this.sobrenome; }; console.log(daniel.nomeCompleto()); // Daniel Adornes console.log(outraPessoa.nomeCompleto()); // Outra Pessoa ... ...
O mesmo princípio se aplica para a possibilidade de adicionar funções a objetos nativos do linguagem, como no exemplo abaixo:
String.prototype.pluralize = function(){ // Algoritmo aqui }; console.log("Pessoa".pluralize()); // Pessoas ... ...
Conclusão
Compreender tal versatilidade da linguagem abre inúmeras possibilidades, além de ajudar a compreender melhor ferramentas como jQuery, ExtJS e outras construídas em cima de JavaScript. Há porém ainda outros conceitos mais avançados, inclusive envolvendo a criação de objetos. Por isso recomendo as seguintes referências:
Nenhum comentário:
Postar um comentário