Você está na página 1de 10

Padres JavaScript

Stoyan Stefanov

Novatec

Authorized Portuguese translation of the English edition of titled JavaScript Patterns, First Edition, ISBN: 978-0596-80675-0 2010, Stoyan Stefanov. This translation is published and sold by permission of O'Reilly Media, Inc.,
the owner of all rights to publish and sell the same.
Traduo em portugus autorizada da edio em ingls do ttulo JavaScript Patterns, First Edition, ISBN: 978-0596-80675-0 2010, Stoyan Stefanov. Esta traduo publicada e vendida com a permisso da O'Reilly Media,
Inc., detentora de todos os direitos para publicao e venda desta obra.
Novatec Editora Ltda. 2011.
Todos os direitos reservados e protegidos pela Lei 9.610 de 19/02/1998. proibida a reproduo desta obra, mesmo
parcial, por qualquer processo, sem prvia autorizao, por escrito, do autor e da Editora.
Editor: Rubens Prates
Traduo: Edgard Damiani
Reviso gramatical: Carla Mello Moreira
Editorao eletrnica: Camila Kuwabata e Carolina Kuwabata
ISBN: 978-85-7522-266-9
Histrico de impresses:
Janeiro/2011

Primeira edio

Novatec Editora Ltda.


Rua Lus Antnio dos Santos 110
02460-000 So Paulo, SP Brasil
Tel.: +55 11 2959-6529
Fax: +55 11 2950-8869
Email: novatec@novatec.com.br
Site: www.novatec.com.br
Twitter: twitter.com/novateceditora
Facebook: facebook.com/novatec
LinkedIn: linkedin.com/in/novatec

Dados

Internacionais de Catalogao na Publicao


(Cmara Brasileira do Livro, SP, Brasil)
Stefanov, Stoyan
Padres JavaScript / Stoyan Stefanov ;
[traduo Edgard Damiani]. -- So Paulo :
Novatec Editora ; Sebastopol, CA. : OReilly,
2010.
Ttulo original: JavaScript patterns.
ISBN 978-85-7522-266-9
1. JavaScript (Linguagem de programao para
computadores) I. Ttulo.

10-13324

CDD-005.133
ndices para catlogo sistemtico:
1. JavaScript : Linguagem de programao :
Computadores : Processamento de dados
005.133

OGF_20101207

(CIP)

captulo 1

Introduo

JavaScript a linguagem da web. Ela comeou como uma forma de manipular alguns
tipos de elementos selecionados em uma pgina web (como imagens ou campos de
formulrios), mas acabou crescendo enormemente. Alm de servir como script de
navegador no lado do cliente, atualmente voc pode usar o JavaScript para programar em uma variedade cada vez maior de plataformas. Voc pode escrever cdigo
no lado do servidor (usando .NET ou Node.js), aplicaes desktop (que funcionam
em todos os sistemas operacionais) e extenses de aplicao (por exemplo, Firefox
ou Photoshop), aplicaes para dispositivos mveis e scripts de linha de comando.
O JavaScript tambm uma linguagem incomum. Ela no possui classes, e funes
so usadas como objetos de primeira classe em vrias tarefas. Inicialmente, a linguagem foi considerada deficiente por vrios desenvolvedores, mas nos ltimos anos esse
sentimento tem mudado. Curiosamente, linguagens como Java e PHP comearam a
adicionar funcionalidades como closures e funes annimas, que os desenvolvedores
JavaScript vm utilizando corriqueiramente h algum tempo.
O JavaScript suficientemente dinmico a ponto de ser possvel faz-lo parecer com
qualquer outra linguagem com a qual voc se sinta confortvel. Mas a melhor abordagem abraar suas diferenas e estudar seus padres especficos.

Padres
Um padro (pattern), no sentido mais amplo da palavra, um tema de eventos ou
objetos recorrentes [...] ele pode ser um template ou modelo utilizado para gerar
coisas (http://en.wikipedia.org/wiki/Pattern).
Em desenvolvimento de software, um padro uma soluo para um problema
comum. Um padro no necessariamente uma soluo de cdigo pronta para ser
copiada e colada, e sim mais uma prtica melhor, uma abstrao til e um modelo
de resoluo de categorias de problemas.
importante identificar padres porque:
Eles nos ajudam a escrever melhores cdigos, utilizando prticas comprovadas
e no reinventando a roda.
17

18

Padres JavaScript

Eles fornecem um nvel de abstrao o crebro pode armazenar apenas um


tanto em dado momento, ento, quando voc pensa em um problema mais
complexo, ajuda no ter de se preocupar com os detalhes de baixo nvel,
encapsulando-os em blocos de construo autocontidos (padres).
Eles melhoram a comunicao entre desenvolvedores e equipes, que costumam
ficar em locais remotos e no se comunicar pessoalmente. O simples fato de
rotular uma tcnica ou abordagem de programao facilita saber se estamos
falando do mesmo assunto. Por exemplo, mais fcil dizer (e pensar) funo
imediata do que esta coisa em que voc encapsula a funo em parnteses
e, no final dela, coloca outro conjunto de parnteses para invocar a funo
exatamente no local onde voc a definiu.
Este livro discute os seguintes tipos de padres:
Padres de projeto (design patterns).
Padres de programao (coding patterns).
Antipadres (antipatterns).
Padres de projeto so aqueles definidos inicialmente pelo livro Gang of Four (o
quarteto, nomeado assim por causa de seus quatro autores), originalmente publicado em um distante 1994 sob a alcunha de Design Patterns: Elements of Reusable
Object-Oriented Software (Padres de Projeto: Elementos Reutilizveis de Software
Orientado a Objeto). Exemplos de padres de projeto so singleton, fbrica (factory),
decorador (decorator), observador (observer) e assim por diante. A questo dos padres de projeto em relao ao JavaScript que, apesar de serem independentes de
linguagem, os padres de projeto foram na sua maior parte estudados do ponto de
vista de linguagens fortemente tipadas, como C++ e Java. Por vezes no faz sentido
algum aplic-los literalmente em uma linguagem fracamente tipada como o JavaScript.
Algumas vezes esses padres buscam contornar problemas relacionados natureza
fortemente tipada das linguagens e da herana baseada em classes. Talvez existam
alternativas mais simples no JavaScript. Este livro discute implementaes JavaScript
de vrios padres de projeto no captulo 7.

Os padres de programao so muito mais interessantes; eles so padres especficos


ao JavaScript, alm de serem boas prticas relacionadas s funcionalidades exclusivas
da linguagem, como os vrios usos de funes. Padres de programao JavaScript
so o principal tpico deste livro.
Voc pode trombar ocasionalmente com um antipadro no livro. Antipadres tm certo
tom negativo ou at mesmo insultante em seu nome, mas este no necessariamente o
caso. Um antipadro no o mesmo que um bug ou um erro de codificao, apenas
uma abordagem comum que causa mais problemas do que solues. Os antipadres
esto marcados claramente com comentrios no cdigo.

Captulo 1 Introduo

19

JavaScript: conceitos
Vamos revisar rapidamente alguns conceitos importantes que fornecem o contexto
para os prximos captulos.

Orientado a objeto
JavaScript uma linguagem orientada a objetos, o que costuma surpreender desenvolvedores que previamente observaram a linguagem e dispensaram-na. Tudo o que
voc v em um trecho de cdigo JavaScript tem boa chance de ser um objeto. Apenas
cinco tipos primitivos no so objetos: numrico, string, booleano, null e undefined, e
os primeiros trs tm representaes correspondentes de objetos na forma de encapsuladores primitivos (discutidos no prximo captulo). Valores primitivos numricos,
booleanos e de string so facilmente convertidos em objetos, seja pelo prprio programador ou, s vezes, nos bastidores pelo interpretador JavaScript.
Funes tambm so objetos. Elas podem ter propriedades e mtodos.
A coisa mais simples que voc pode fazer em uma linguagem definir uma varivel.
Bem, no JavaScript, ao definir uma varivel, voc j est lidando com objetos. Primeiro,
a varivel automaticamente torna-se uma propriedade de um objeto interno conhecido
como um Objeto de Ativao (ou uma propriedade do objeto global, caso seja uma
varivel global). Segundo, essa varivel tambm , na verdade, algo como um objeto,
porque ela tem suas propriedades particulares (chamadas atributos) que determinam
se a varivel pode ser modificada, apagada ou enumerada em um loop for-in. Esses
atributos no so expostos explicitamente na ECMAScript 3, mas a edio 5 oferece
mtodos descritores especiais para manipul-los.
Afinal, o que so esses objetos? Eles devem ser um tanto especiais, j que podem fazer
tantas coisas. Na verdade eles so extremamente simples. Um objeto apenas uma
coleo de propriedades nomeadas, uma lista de pares nome-valor (quase idntico a
um array associativo em outras linguagens). Algumas das propriedades podem ser
funes (objetos-funo), que, no caso, chamamos de mtodos.
Outra coisa sobre os objetos que voc cria que voc pode modific-los a qualquer
momento (apesar de a ECMAScript 5 introduzir APIs que previnem mutaes). Voc
pode pegar um objeto e adicionar, remover e atualizar seus membros. Se estiver preocupado sobre privacidade e acesso, tambm veremos padres para isso.
E uma ltima coisa para se ter em mente que existem dois tipos principais de objetos:

Nativo
Descrito pela norma ECMAScript.

20

Padres JavaScript

De hospedeiro (host)
Definido pelo ambiente hospedeiro (por exemplo, o ambiente do navegador web).
Os objetos nativos tambm podem ser categorizados como embutidos (por exemplo,
Array, Date) ou definidos pelo usurio (var o = {};).
Objetos de hospedeiro so, por exemplo, o objeto window e todos os objetos DOM. Se
quiser saber se voc est utilizando objetos de hospedeiro, tente executar seu cdigo
em um ambiente diferente do ambiente de navegador. Se funcionar corretamente,
provavelmente voc est usando apenas objetos nativos.

Sem classes
Voc ver esta afirmao repetida em vrias ocasies ao longo do livro: no h classes
no JavaScript. Isso um conceito novo para os programadores experientes de outras
linguagens e leva mais do que algumas repeties, e mais do que um pouco de esforo, para desaprender classes e aceitar que o JavaScript lida apenas com objetos.
No ter classes torna os seus programas mais curtos voc no precisa ter uma classe
para criar um objeto. Considere essa criao de objeto no estilo Java:
// criao de objeto no estilo Java
HelloOO hello_oo = new HelloOO();

Repetir trs vezes a mesma coisa parece um exagero quando se quer criar objetos
simples. E normalmente desejamos manter nossos objetos simples.
No JavaScript, voc cria um objeto em branco quando precisa de um e, ento, comea a adicionar membros interessantes a ele. Voc compe objetos adicionando
tipos primitivos, funes e outros objetos a eles como sendo suas propriedades. Um
objeto em branco no totalmente vazio; ele j vem com algumas propriedades
embutidas, mas no possui propriedades particulares. Falaremos mais sobre isso no
prximo captulo.
Uma das regras gerais do livro Gang of Four diz assim: Prefira composio de objetos a herana de classes. Isso significa que, se voc puder criar objetos a partir de
elementos disponveis que esto dando sopa, isso uma abordagem muito melhor
do que criar longas cadeias de herana e classificaes pai-filho. No JavaScript, fcil
seguir esse conselho simplesmente porque no h classes, e composio de objetos
o que voc vai acabar fazendo de qualquer maneira.

Prottipos
O JavaScript possui herana, apesar de isso ser apenas uma das formas de reutilizar
cdigo (e teremos um captulo inteiro sobre reutilizao de cdigo). Herana pode

Captulo 1 Introduo

21

ser realizada de vrias formas, normalmente fazendo uso de prottipos. Um prottipo


um objeto (o que no uma surpresa) e toda funo que voc cria recebe automaticamente uma propriedade prototype que aponta para um novo objeto em branco.
Esse objeto quase idntico a um objeto criado a partir de um objeto literal ou pelo
construtor Object(), exceto que sua propriedade constructor aponta para a funo que
voc criou, e no para o objeto embutido Object(). Voc pode adicionar membros a esse
objeto em branco e, mais tarde, ter outros objetos herdando desse objeto e utilizando
as propriedades dele como se fossem criadas por voc.
Discutiremos herana em detalhes, mas por ora tenhamos em mente que o prottipo
um objeto (no uma classe ou algo especial) e que toda funo tem uma propriedade prototype.

Ambiente
Programas JavaScript precisam de um ambiente para serem executados. O habitat
natural de um programa JavaScript o navegador web, mas esse no o nico ambiente disponvel. Os padres mostrados neste livro so na sua maioria relacionados
ao ncleo (core) do JavaScript (ECMAScript), ento eles so independentes do ambiente. As excees so:
o captulo 8, que lida especificamente com padres de navegador;
alguns outros exemplos que ilustram aplicaes prticas de um padro.
Os ambientes podem fornecer objetos de hospedeiro prprios, que no so definidos na
norma ECMAScript e que podem ter comportamento no especificado ou indefinido.

ECMAScript 5
O ncleo (core) da linguagem de programao JavaScript (que exclui o DOM, o
BOM e objetos de hospedeiro extras) baseado na norma ECMAScript, ou ES para
abreviar. A verso 3 da norma foi aceita oficialmente em 1999 e a verso atualmente
implementada nos navegadores. A verso 4 foi abandonada e a verso 5 foi aprovada
em dezembro de 2009, 10 anos aps a verso prvia.
A verso 5 inclui na linguagem alguns objetos embutidos, propriedades e mtodos
novos, mas sua incluso mais importante foi o chamado modo estrito, que, na verdade, remove algumas funcionalidades da linguagem, tornando os programas mais
simples e menos propensos a erros. Por exemplo, o uso da instruo with tem sido
questionado ao longo dos anos. Agora, no modo estrito do ES5 ela gera um erro,
apesar de no haver problemas em utiliz-la no modo no estrito. O modo estrito
ativado por uma string comum, que as implementaes mais antigas da linguagem
simplesmente ignoram. Isso significa que o uso do modo estrito compatvel com

22

Padres JavaScript

as verses anteriores, j que ele no gera erros em navegadores mais antigos que no
o reconheam.
Uma vez por escopo (seja escopo de funo, escopo global ou no incio de uma string
passada com eval()), voc pode usar a seguinte string:
function my() {
"use strict";
// o resto da funo...
}

Isso significa que o cdigo na funo executado dentro do subconjunto estrito da


linguagem. No caso de navegadores antigos, isso apenas uma string no atribuda
a uma varivel, ento ela no usada, e ainda assim no um erro.
O plano para a linguagem que, no futuro, o modo estrito seja o nico modo permitido. Nesse sentido, a ES5 uma verso de transio os desenvolvedores so
encorajados, mas no forados, a escrever cdigo que funcione no modo estrito.
Este livro no explora padres relacionados s incluses especficas da ES5, porque
quando o estvamos escrevendo no havia navegadores que a implementassem. Mas
os exemplos neste livro promovem uma transio ao novo padro:
garantindo que as amostras de cdigo oferecidas no iro gerar erros no modo
estrito;
evitando e indicando construes obsoletas, como arguments.callee;
invocando padres da ES3 que tenham equivalentes na ES5 embutidos, como
Object.create().

JSLint
JavaScript uma linguagem interpretada sem verificaes estticas em tempo de
compilao. Assim, possvel gerar um programa defeituoso com apenas um erro de
digitao sem se aperceber do fato. aqui que o JSLint ajuda.
O JSLint (http://jslint.com) uma ferramenta de qualidade de cdigo JavaScript,
criada por Douglas Crockford, que inspeciona seu cdigo e avisa sobre problemas
em potencial. altamente recomendvel que voc execute seu cdigo por meio do
JSLint. A ferramenta vai ferir seus sentimentos, como o prprio criador alerta, mas
apenas no incio. Voc pode aprender rapidamente com seus erros e adotar hbitos
essenciais de um programador JavaScript profissional. No ter erros JSLint em seu
cdigo tambm ajuda a ter mais confiana no cdigo, sabendo que, na pressa, voc
no cometeu uma simples omisso ou erro de sintaxe.

23

Captulo 1 Introduo

No prximo captulo, voc ver que o JSLint bastante mencionado. Todo o cdigo
no livro passa com sucesso na verificao do JSLint (usando as configuraes padro
correntes no momento em que escrevemos o cdigo), exceto por algumas poucas
ocasies claramente demarcadas como antipadres.
Em suas configuraes padro, o JSLint espera que seu cdigo seja compatvel com
o modo estrito.

Objeto console
O objeto console utilizado ao longo do livro. Esse objeto no faz parte da linguagem,
e sim do ambiente, e est presente na maioria dos navegadores atuais. No Firefox,
por exemplo, ele vem com a extenso Firebug. O console do Firebug possui uma
interface de usurio que lhe permite digitar e testar rapidamente trechos de cdigo
JavaScript, alm de brincar com a pgina carregada atualmente (Figura 1.1). Ele
tambm altamente recomendado como ferramenta de aprendizado e explorao.
Funcionalidades semelhantes esto disponveis nos navegadores WebKit (Safari e
Chrome) como parte do Web Inspector, e no IE a partir da verso 8 como parte das
Developer Tools (Ferramentas do Desenvolvedor).
A maioria dos exemplos de cdigo no livro usa o objeto console, em vez de usar alert()
ou ter de atualizar a pgina atual, porque isso uma maneira simples e no intrusiva
de imprimir sadas.

Figura 1.1 Usando o console do Firebug.

24

Padres JavaScript

Normalmente usamos o mtodo log(), que imprime todos os parmetros passados


a ele, e algumas vezes usamos o mtodo dir(), que enumera o objeto passado a ele e
imprime todas as propriedades. Aqui est um exemplo de sua utilizao:
console.log("test", 1, {}, [1,2,3]);
console.dir({one: 1, two: {three: 3}});

Quando estiver digitando no console, no h a necessidade de usar console.log(); voc


pode simplesmente omiti-lo. Para evitar confuso, alguns trechos de cdigo no o
utilizam e assumem que voc esteja testando o cdigo no console.
window.name === window['name']; // true

Isso como se usssemos o seguinte:


console.log(window.name === window['name']);

e ele tivesse imprimido true no console.

Você também pode gostar