<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <id>tag:www.worksforme.com.br,2005:/feeds</id>
  <link type="text/html" href="http://www.worksforme.com.br" rel="alternate"/>
  <link type="application/atom+xml" href="http://www.worksforme.com.br/feeds.atom" rel="self"/>
  <title>Works For Me</title>
  <updated>2011-03-10T15:06:56Z</updated>
  <entry>
    <id>tag:www.worksforme.com.br,2005:Post/2</id>
    <published>2011-03-10T15:06:56Z</published>
    <updated>2011-03-10T15:06:56Z</updated>
    <link type="text/html" href="http://www.worksforme.com.br/entendendo-os-operadores==e===" rel="alternate"/>
    <title>Entendendo os operadores "==" e "==="</title>
    <content type="html">&lt;p&gt;Em JavaScript os operadores "==" e "===" determinam se dois valores s&#227;o iguais utilizando defini&#231;&#245;es diferentes de igualdade. Quem j&#225; deu uma olhada no c&#243;digo do jQuery j&#225; deve ter visto que o operador "===" &#233; bastante utilizado, e deve ter se perguntado o que ele significa e por que n&#227;o utilizar o mais comum "==". As diferen&#231;as s&#227;o pequenas, por&#233;m, entend&#234;-las bem pode te salvar um bom tempo de debug.&lt;/p&gt;

&lt;h3&gt;Igualdade segundo o operador "=="&lt;/h3&gt;

&lt;p&gt;A compara&#231;&#227;o de tipos primitivos (number, string e boolean) &#233; feita por valor, isto &#233;, se possu&#237;rem o mesmo tipo e valor eles s&#227;o considerados iguais. Se os tipos forem diferentes e um dos operandos for do tipo string ou boolean, este &#233; convertido para number implicitamente e depois comparado. Exemplo:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;"abc" == "abc"    // true
5 == 7            // false
"42" == 42        // true (convers&#227;o impl&#237;cita)
1 == true         // true (convers&#227;o impl&#237;cita)
"0" == false      // true (convers&#227;o impl&#237;cita)
null == undefined // true
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Se os operandos forem de um tipo n&#227;o-primitivo (objects, arrays e functions) eles somente ser&#227;o considerados iguais se referenciarem ao mesmo objeto, mesmo que eles tenham suas propriedades ou valores (no caso de arrays) iguais. Exemplo:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var point1 = { x: 10, y: 5 };
var point2 = { x: 10, y: 5 };
var point3 = point1;

point1 == point2  // false
point1 == point3  // true
[1,2] == [1,2]    // false
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Igualdade segundo o operador "==="&lt;/h3&gt;

&lt;p&gt;Este operador, chamado de operador de "identidade", verifica se os operandos s&#227;o id&#234;nticos, sem aplicar qualquer tipo de convers&#227;o. Exemplo:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;"abc" === "abc"     // true
5 === 7             // false
"42" === 42         // false
1 === true          // false
"0" === false       // false
null === undefined  // false
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Para a compara&#231;&#227;o de objetos de tipos n&#227;o-primitivos o comportamento do operador "===" &#233; o mesmo do "==".&lt;/p&gt;

&lt;p&gt;Existe ainda uma exce&#231;&#227;o para o caso de um dos operandos ser do tipo NaN (not-a-number): qualquer valor comparado a NaN &#233; sempre false, seja com "==" ou "===", inclusive o pr&#243;prio NaN!&lt;/p&gt;

&lt;h3&gt;Conclus&#227;o&lt;/h3&gt;

&lt;p&gt;Para quem programa em outras linguagens o comportamento do operador "===" deve parecer mais intuitivo. Esse operador &#233; certamente mais seguro e por isso &#233; comum v&#234;-lo em bibliotecas como jQuery.
A menos que voc&#234; saiba exatamente os tipos envolvidos e quais convers&#245;es ser&#227;o aplicadas (o que pode ser bem complicado em JavaScript), minha recomenda&#231;&#227;o &#233; que voc&#234; sempre utilize o operador "===" para evitar surpresas :)&lt;/p&gt;</content>
    <author>
      <name>Eduardo Cobuci</name>
    </author>
  </entry>
  <entry>
    <id>tag:www.worksforme.com.br,2005:Post/1</id>
    <published>2011-02-22T21:04:40Z</published>
    <updated>2011-02-28T02:40:51Z</updated>
    <link type="text/html" href="http://www.worksforme.com.br/orientacao-a-objetos-em-javascript" rel="alternate"/>
    <title>Orienta&#231;&#227;o a objetos em JavaScript</title>
    <content type="html">&lt;p&gt;Ao contr&#225;rio do que muitos pensam, JavaScript permite sim orienta&#231;&#227;o &#224; objetos. Um tipo um tanto diferente &#233; verdade (sem classes), por outro lado, permite coisas muito interessantes como mixins e outras m&#225;gicas t&#237;picas de linguagens din&#226;micas.
Neste artigo vou mostrar como desenvolver em JavaScript utilizando orienta&#231;&#227;o &#224; objetos e outros truques de umas das linguagens mais utilizadas do mundo.&lt;/p&gt;

&lt;h3&gt;Classes&lt;/h3&gt;

&lt;p&gt;Em JavaScript n&#227;o existe o conceito de classes como em Java ou C#, entretanto, &#233; poss&#237;vel criar pseudo-classes, inclusive com suporte a heran&#231;a. Para criar uma &#8220;classe&#8221; em JavaScript deve-se definir uma fun&#231;&#227;o construtor desta forma:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function Car(m, y) {
    this.model = m;
    this.year = y;
    this.getAge = function() {
        return (new Date()).getFullYear() - this.year;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ao invocar esta fun&#231;&#227;o com o operador &#8220;new&#8221;, uma inst&#226;ncia/objeto desta classe &#233; criada:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var myCar = new Car("Nissan Skyline", 2008);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Diferentemente do que acontece em outras linguagens, em JavaScript a simples atribui&#231;&#227;o de um valor &#224; uma vari&#225;vel j&#225; &#233; suficiente para declar&#225;-la e inici&#225;-la. Note tamb&#233;m que a palavra-chave &#8220;this&#8221; funciona de forma parecida com Java e C#, ou seja, refere-se &#224; inst&#226;ncia que est&#225; sendo criada. Desta forma podemos acessar as vari&#225;veis criadas pelo construtor como propriedades do objeto:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;myCar.model     // "Nissan Skyline"
myCar.year      // 2008
myCar.getAge()  // 2
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Em nossa classe h&#225; um m&#233;todo chamado "getAge", este m&#233;todo &#233; na verdade uma propriedade de cada objeto criado. Isso significa que cada objeto criado ir&#225; alocar uma parte da mem&#243;ria para armazen&#225;-lo, podendo consumir muita mem&#243;ria caso muitas inst&#226;ncias desta classe sejam criadas. Para resolver este problema deve-se utilizar o prototype da classe para definir seus m&#233;todos.&lt;/p&gt;

&lt;h3&gt;Prototypes&lt;/h3&gt;

&lt;p&gt;Todo objeto em JavaScript possui uma refer&#234;ncia interna a um objeto chamado &#8220;prototype&#8221;. Toda propriedade do prototype de uma classe &#233; tamb&#233;m uma propriedade dos objetos desta classe, ou seja, todo objeto herda as propriedades de seu prototype. Uma melhor vers&#227;o da classe &#8220;Car&#8221; ficaria assim:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function Car(m, y) {
    this.model = m;
    this.year = y;
}

Car.prototype.getAge = function() {
    return (new Date()).getFullYear() - this.year;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Desta forma continuamos podendo acessar o m&#233;todo &#8220;getAge&#8221;, por&#233;m, sem ter de aloc&#225;-lo para cada objeto. Note que a defini&#231;&#227;o do m&#233;todo &#233; feita depois da classe, isso demonstra que podemos adicionar membros a uma classe a qualquer momento atrav&#233;s de seu prototype. Para determinar se uma propriedade foi definida em seu construtor ou herdada de seu prototype basta chamar a fun&#231;&#227;o &#8220;hasOwnProperty()&#8221; do objeto:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var c = new Car("Honda Civic", 1995);
c.hasOwnProperty("model"); // true
c.hasOwnProperty("getAge");    // false - Herdada do prototype
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Propriedades e m&#233;todos est&#225;ticos&lt;/h3&gt;

&lt;p&gt;Propriedades e m&#233;todos de classe, tamb&#233;m conhecidos como &#8220;est&#225;ticos&#8221;, s&#227;o bastante utilizados em Java e C#. S&#227;o membros que n&#227;o est&#227;o em uma inst&#226;ncia/objeto especifico, mas sim diretamente na classe. Um exemplo de classe que possui este tipo de propriedade/m&#233;todo &#233; a classe &#8220;Math&#8221;, onde temos a propriedade &#8220;Math.PI&#8221;, que retorna a constante PI, e o m&#233;todo &#8220;Math.max(a, b)&#8221;, que retorna o maior dos dois argumentos.
Para criar um membros est&#225;tico basta atribu&#237;-los diretamente &#224; classe:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Painter.paint = function(o, c)
{
    o.color = c;
}

Painter.paint(car, "black");
car.color; // "black"
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Heran&#231;a&lt;/h3&gt;

&lt;p&gt;Como eu disse no in&#237;cio, em JavaScript n&#227;o h&#225; o conceito de classes como em Java ou C#. Ainda assim, isso n&#227;o significa que n&#227;o seja poss&#237;vel estabelecer heran&#231;a entre tipos. Suponha que agora precisamos criar um carro que armazene sua velocidade e possa ser acelerado. Para isso, vamos criar uma nova classe que extenda a classe &#8220;Car&#8221;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function AccelerableCar(m, y, s){
     Car.call(this, m, y); // chama o construtor da classe m&#227;e
     this.maxSpeed = s;
     this.speed = 0;
}

AccelerableCar.prototype.accelerate = function(by){
     this.speed = Math.min(this.speed + by, this.maxSpeed);
}

AccelerableCar.prototype = new Car(); // realiza a heran&#231;a!
AccelerableCar.prototype.contructor = AccelerableCar; // a propriedade 'constructor' do prototype referencia a fun&#231;&#227;o construtor da classe

var ac = new AccelerableCar('Porshe Carrera', 2005, 350);
ac.model                     // 'Porshe Carrera'
ac.year            // 2005
ac.speed                     // 0
ac.accelerate(150);
ac.speed                     // 150
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Como voc&#234; pode notar, criar uma sub-classe em JavaScript n&#227;o &#233; t&#227;o simples. Primeiro, em seu construtor &#233; necess&#225;rio ter certeza que o construtor da classe m&#227;e &#233; chamado atrav&#233;s do m&#233;todo &#8220;call&#8221;. Em JavaScript toda fun&#231;&#227;o possui uma &#8220;sub-fun&#231;&#227;o&#8221; chamada &#8220;call&#8221;, esta fun&#231;&#227;o executa a fun&#231;&#227;o original trocando o objeto interno &#8220;this&#8221; pelo rimeiro argumento. Depois, deve-se atribuir ao prototype da classe filha uma inst&#226;ncia da classe m&#227;e, desta forma a classe filha adquire todos os membros da classe m&#227;e.
Por fim, deve-se atribuir a propriedade &#8220;constructor&#8221; do prototype da classe filha a fun&#231;&#227;o construtor da mesma. Isso &#233; importante pois ao executar esta linha &#8220;AccelerableCar.prototype = new Car()&#8221; o prototype de &#8220;AccelerableCar&#8221; &#233; alterado para &#8220;Car&#8221; e seu construtor passa a ser o de &#8220;Car&#8221;.&lt;/p&gt;

&lt;h3&gt;M&#243;dulos, extendendo sem usar heran&#231;a&lt;/h3&gt;

&lt;p&gt;Algumas linguagens de programa&#231;&#227;o como, por exemplo, Ruby, disp&#245;em de um recurso muito interessante chamado de m&#243;dulo. Um m&#243;dulo &#233; bastante parecido com uma classe, pode conter m&#233;todos, propriedades e at&#233; classes, por&#233;m, n&#227;o pode ser instanciado. Em contra-partida, uma classe pode &#8220;herdar&#8221; de quantos m&#243;dulos quiser e, diferentemente do que acontece com interfaces, os m&#233;dotos de um m&#243;dulos s&#227;o implementados no pr&#243;prio m&#243;dulo. Isso &#233; conhecido como &#8220;mixin&#8221;, uma forma de fazer de heran&#231;a m&#250;ltipla, mas sem seus problemas.
Em JavaScript podemos simular m&#243;dulos de forma parecida como fazemos para simular classes, com a difer&#234;n&#231;a de que por convens&#227;o os m&#233;todos de um m&#243;dulo s&#227;o est&#225;ticos, e seu construtor emite uma exce&#231;&#227;o caso seja invocado. Abaixo um exemplo de um m&#243;dulo que define um m&#233;todo para serializar um objeto simples em JSON:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function Serializable(){
    throw "You can&#8217;t create an object from a module!";
}

Serializable.serialize = function(o) {
    obj = o || this;
    var members = [];
    for(m in obj) {
         if(typeof obj[m] != "function")
              members.push("'" + m + "':'" + obj[m].toString() + "'");
    }
    return "{" + members.join(",") + "}";
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Agora podemos usar este m&#243;dulo em qualquer classe que quisermos:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Car.prototype.serialize = Serializable.serialize;

var myCar = new Car("Porshe Carrera", 2010);
alert(myCar.serialize()); // {'model':'Porshe Carrera','year':'2010'}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Depois do mixin a classe classe &#8220;Car&#8221; passa a ter o m&#233;doto &#8220;serialize&#8221; de &#8220;Serializable&#8221;. Voc&#234; tamb&#233;m deve ter notado que este processo de mixin &#8220;manual&#8221; se torna invi&#225;vel caso o m&#243;dulo possua muitos m&#233;todos. Para resolver isso, podemos criar um helper para fazer o trabalho pesado:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function Module(){}
Module.mixin(source, target)
{
    for(m in source) {
         if(typeof source[m] == "function")
              target.prototype[m] = source[m];
    }
}

Module.mixin(Serializable, Car);
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Namespaces&lt;/h3&gt;

&lt;p&gt;Uma boa-pr&#225;tica em programa&#231;&#227;o orientada &#224; objetos &#233; definir namespaces para organizar o c&#243;digo e evitar conflitos, principalmente em projetos grandes. Ainda que n&#227;o exista nenhum suporte &#224; namespaces na linguagem JavaScript, &#233; poss&#237;vel utilizar objetos para tal. No exemplo abaixo uma namespace "com.game" e define a classe &#8220;Car&#8221; dentro dela:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var com = {};
com.game = {};

com.game.Car = function(m, y) { /* ... */ }

var c = new com.game.Car("Audi TT", 2002);
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Conclus&#227;o&lt;/h3&gt;

&lt;p&gt;JavaScript apesar n&#227;o possuir suporte nativo a conceitos tradicionais de orienta&#231;&#227;o &#224; objetos, gra&#231;as &#224; sua natureza din&#226;mica e flex&#237;vel, permite que tais funcionalidades sejam simuladas de maneira bastante satisfat&#243;ria e, em alguns casos, melhor que em linguagens orientadas &#224; objetos tradicionais.
Ainda que seja importante entender como tudo isso &#233; poss&#237;vel, &#233; importante tamb&#233;m frisar que existem diversos frameworks JavaScript (como Ext JS, Dojo, Google Closure entre outros) que possuem helpers que facilitam em muito a cria&#231;&#227;o de aplica&#231;&#245;es orientadas &#224; objetos em JavaScript&lt;/p&gt;</content>
    <author>
      <name>Eduardo Cobuci</name>
    </author>
  </entry>
</feed>
