<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"> 
  <id>http://loopinfinito.com.br/</id>
  <title>Loop Infinito</title>
  <icon>http://loopinfinito.com.br/images/favicon.png</icon>
  <updated>2014-10-28T21:24:35-07:00</updated>
  <link rel="self" href="http://loopinfinito.com.br/feed/index.xml" />
  <link href="http://loopinfinito.com.br/" />
  
  <entry>
    <id>http://loopinfinito.com.br/2014/10/29/hoisting-e-escopo-em-javascript</id>
    <title>Hoisting e escopo em JavaScript</title>
    <updated>2014-10-29T00:00:00-07:00</updated>
    <link href="http://loopinfinito.com.br/2014/10/29/hoisting-e-escopo-em-javascript/" />
    <author>
      <name>Caio Gondim</name>
      <uri>http://twitter.com/caio_gondim</uri>
    </author>
    <content type="html">
      
      
      &lt;p&gt;&lt;img itemprop=&quot;thumbnailUrl&quot; src=&quot;http://loopinfinito.com.br/images/posts/2014-10-29-javascript-hoisting.jpg&quot; alt=&quot;Hoisting e escopo em JavaScript&quot; title=&quot;Hoisting e escopo em JavaScript&quot; width=&quot;700&quot; height=&quot;432&quot; /&gt;&lt;/p&gt;
      
      
&lt;p&gt;O JavaScript é uma linguagem cheia de pequenas surpresas que pode espantar até o mais experiente programador. Vamos tomar como exemplo o trecho de código abaixo. Você sabe quais valores serão impressos?&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='c1'&gt;// Exemplo 1&lt;/span&gt;
&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;a&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;

&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;foo&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;a&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;a&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;
  &lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;a&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='nx'&gt;foo&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt;

&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;a&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Pela “lógica”, deveria ser primeiro impreso &lt;code&gt;1&lt;/code&gt;, &lt;code&gt;1&lt;/code&gt; e &lt;code&gt;2&lt;/code&gt;, correto? &lt;strong&gt;Não&lt;/strong&gt;. E neste outro trecho de código, qual será a saída?&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='c1'&gt;// Exemplo 2&lt;/span&gt;
&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;foo&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;bar&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;

  &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;bar&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt;

  &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;bar&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='mi'&gt;8&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;foo&lt;/span&gt;&lt;span class='p'&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Se você não respondeu &lt;code&gt;undefined&lt;/code&gt;, &lt;code&gt;2&lt;/code&gt; e &lt;code&gt;1&lt;/code&gt; para o exemplo 1 e &lt;code&gt;8&lt;/code&gt; para o exemplo 2, aconselho a leitura deste &lt;em&gt;post&lt;/em&gt;. Aqui vamos discutir um pouco sobre o &lt;strong&gt;&lt;em&gt;hoisting&lt;/em&gt;&lt;/strong&gt; no JavaScript. Mas antes de elaborarmos mais sobre os motivos que levaram nosso código a se comportar de tal forma, vamos de volta ao básico e falar sobre &lt;strong&gt;escopo&lt;/strong&gt;.&lt;/p&gt;

&lt;h2 id=&quot;escopo&quot;&gt;Escopo&lt;/h2&gt;

&lt;p&gt;Escopo em JavaScript é um tópico que gera bastante confusão para iniciantes na linguagem. Apesar de pertencer a família das linguagens baseadas em C, o escopo em JavaScript não funciona da mesma forma como em C, C++ ou mesmo Java. Vamos usar o seguinte trecho de código em C como exemplo:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='c'&gt;&lt;span class='c1'&gt;// Exemplo 3&lt;/span&gt;
&lt;span class='cp'&gt;#include &amp;lt;stdio.h&amp;gt;&lt;/span&gt;

&lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='nf'&gt;main&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='n'&gt;printf&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;%d&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='c1'&gt;//=&amp;gt; 1&lt;/span&gt;

  &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='n'&gt;printf&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;%d&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='c1'&gt;//=&amp;gt; 2&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;

  &lt;span class='n'&gt;printf&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;%d&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='c1'&gt;//=&amp;gt; 1&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;No código acima, o exemplo 3 irá imprimir &lt;code&gt;1&lt;/code&gt;, &lt;code&gt;2&lt;/code&gt; e &lt;code&gt;1&lt;/code&gt;. Isso acontece porque em C (assim como Java e C++), temos escopo por bloco. Em JavaScript só temos escopo a nível de função. O código anterior traduzido de uma forma “ingênua” pra JavaScript seria algo assim:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='c1'&gt;// Exemplo 4&lt;/span&gt;
&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;a&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;
&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;a&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='c1'&gt;//=&amp;gt; 1&lt;/span&gt;

&lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kc'&gt;true&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;a&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;
  &lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;a&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='c1'&gt;//=&amp;gt; 2&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;a&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='c1'&gt;//=&amp;gt; 2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Mas este código — exemplo 4 — não se comporta da mesma forma que o código anterior em C — exemplo 3. Repare que o bloco &lt;code&gt;if&lt;/code&gt; não cria um escopo. Logo, quando a variável recebe o valor &lt;code&gt;2&lt;/code&gt;, ela continuará com este mesmo valor mesmo fora do bloco &lt;code&gt;if&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Para criarmos um escopo dentro do &lt;code&gt;if&lt;/code&gt; temos que usar uma função — uma &lt;abbr title='Immediately-invoked function expression'&gt;IIFE&lt;/abbr&gt; — pois, em JavaScript, esta é a única ferramenta que temos para criar um escopo.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='c1'&gt;// Exemplo 5&lt;/span&gt;
&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;a&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;
&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;a&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='c1'&gt;//=&amp;gt; 1&lt;/span&gt;

&lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kc'&gt;true&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;a&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;
    &lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;a&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='c1'&gt;//=&amp;gt; 2&lt;/span&gt;
  &lt;span class='p'&gt;}())&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;a&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='c1'&gt;//=&amp;gt; 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Agora sim nosso algoritmo em JavaScript está se comportando de forma semelhante ao nosso código anterior em C. Mesmo sendo considerada como uma linguagem que pertence a família C, escopo em JavaScript funciona de um modo bastante diferente. Lembre-se: &lt;strong&gt;escopo em JavaScript apenas com o uso de funções&lt;/strong&gt;. E com o uso de &lt;em&gt;closures&lt;/em&gt; podemos criar escopos onde e quando quisermos em nosso código, simulando assim o comportamento de outras linguagens.&lt;/p&gt;

&lt;h3 id=&quot;declarao_e_nomes_no_escopo&quot;&gt;Declaração e nomes no escopo&lt;/h3&gt;

&lt;p&gt;Existem 4 maneiras de um nome entrar em um escopo em JavaScript:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Definido pela linguagem&lt;/strong&gt;: todo escopo possui o &lt;code&gt;this&lt;/code&gt;, e caso seja uma função, também o &lt;code&gt;arguments&lt;/code&gt;.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Parâmetros de uma função&lt;/strong&gt;: caso uma função seja chamada na forma &lt;code&gt;foo(a, b)&lt;/code&gt;, &lt;code&gt;a&lt;/code&gt; e &lt;code&gt;b&lt;/code&gt; entram no escopo da função.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Declaração de uma função&lt;/strong&gt;: funções declaradas na forma &lt;code&gt;function foo() {}&lt;/code&gt;.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Declaração de uma variável&lt;/strong&gt;: variáveis declaradas como &lt;code&gt;var bar&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Porém, para cada diferente método de entrada no escopo há diferença na ordem de resolução de nomes. Alguns podem ser resolvidos primeiro mesmo aparecendo ao fim do escopo, enquanto outros podem ter apenas seus nomes resolvidos, sem ter seus valores inicializados. E é esse comportamento não explicito de resolução de nomes e inicialização de valores do JavaScript que foi batizado como &lt;strong&gt;&lt;em&gt;hoisting&lt;/em&gt;&lt;/strong&gt; por &lt;a href=&quot;http://twitter.com/bcherry&quot;&gt;Ben Cherry&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;hoisting&quot;&gt;Hoisting&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://dictionary.reference.com/browse/hoist&quot;&gt;&lt;em&gt;Hoist&lt;/em&gt; em inglês&lt;/a&gt; significa levantar ou suspender algo através de um aparato mecânico. Em bom português, significa usar o guindaste para elevar um objeto. E é isto o que acontece em JavaScript quando declaramos uma variável ou função. Sua declaração é “elevada” para o topo do escopo.&lt;/p&gt;

&lt;p&gt;Apesar de não ser óbvio, o modo como o &lt;em&gt;hoisting&lt;/em&gt; funciona é fácil de ser entendido. Vamos estudar todos os casos e saber como se comporta mais esse &lt;em&gt;dark corner&lt;/em&gt; da nossa querida linguagem.&lt;/p&gt;

&lt;h3 id=&quot;variable_hoisting&quot;&gt;Variable hoisting&lt;/h3&gt;

&lt;p&gt;Toda vez que uma variável é definida, sua &lt;strong&gt;declaração&lt;/strong&gt; é &lt;em&gt;hoisted&lt;/em&gt;, mas não sua inicialização. O que quer dizer que a declaração da variável vai para cima do escopo antes mesmo do código ser executado, mas esta variável não recebe nenhum valor e permanece como &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='c1'&gt;// Exemplo 6&lt;/span&gt;
&lt;span class='c1'&gt;// Irá imprimir o erro dentro do `catch`&lt;/span&gt;
&lt;span class='k'&gt;try&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;a&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='k'&gt;catch&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;e&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;error&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;A variável `a` não foi definida.&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='c1'&gt;// Exemplo 7&lt;/span&gt;
&lt;span class='c1'&gt;// Irá imprimir `undefined`&lt;/span&gt;
&lt;span class='k'&gt;try&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;a&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;a&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='k'&gt;catch&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;e&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;error&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;A variável `a` não foi definida.&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Reparem no código acima que no exemplo 6, quando tentamos imprimir o valor de &lt;code&gt;a&lt;/code&gt;, recebemos um erro pois esta variável não existe. Já no exemplo 7, &lt;code&gt;undefined&lt;/code&gt; será impresso, mesmo tendo a declaração de &lt;code&gt;a&lt;/code&gt; depois do do comando &lt;code&gt;console.log&lt;/code&gt;. Ali ocorreu um &lt;code&gt;hoisting&lt;/code&gt; da &lt;strong&gt;declaração&lt;/strong&gt; da variável &lt;code&gt;a&lt;/code&gt;, mas não da sua &lt;strong&gt;inicialização&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;O código do exemplo 7 se comporta da mesma forma que este no exemplo 8:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='c1'&gt;// Exemplo 8&lt;/span&gt;
&lt;span class='c1'&gt;// Irá imprimir `undefined`&lt;/span&gt;
&lt;span class='k'&gt;try&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;a&lt;/span&gt;
  &lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;a&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='nx'&gt;a&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='k'&gt;catch&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;e&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;error&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;a não existe no contexto atual&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;No código acima — exemplo 8 — reescrevemos o exemplo 7 de tal forma que faça mais sentido para nós, já que este código será executado de forma linear.&lt;/p&gt;

&lt;p&gt;Repare que apenas a &lt;strong&gt;declaração&lt;/strong&gt; da variável vai para o topo, mas não sua inicialização. Esta continua no mesmo lugar em que definimos no nosso código. Por isso recebemos um &lt;code&gt;undefined&lt;/code&gt; quando tentamos acessar seu valor.&lt;/p&gt;

&lt;p&gt;&lt;q class='pushing-quotes'&gt;
  Apenas a &lt;strong&gt;declaração&lt;/strong&gt;de uma variável é hoisted, não sua inicialização.&lt;/q&gt;&lt;/p&gt;

&lt;h3 id=&quot;function_hoisting&quot;&gt;Function hoisting&lt;/h3&gt;

&lt;p&gt;O &lt;em&gt;hosting&lt;/em&gt; com funções acontece de maneira diferente. Aqui, não só o nome da função é &lt;em&gt;hoisted&lt;/em&gt; como também seu corpo.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='c1'&gt;// Exemplo 9&lt;/span&gt;
&lt;span class='nx'&gt;foo&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt;
&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;foo&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;O código acima irá imprimir &lt;code&gt;bar&lt;/code&gt;, sem nenhum erro. Mesmo executando uma função antes mesmo de ser definida. Isso porque tanto o nome da função como seu corpo são &lt;em&gt;hoisted&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Vamos analisar novamente o exemplo 2 que apareceu logo no começo do &lt;em&gt;post&lt;/em&gt;. Por que seu &lt;em&gt;output&lt;/em&gt; é &lt;code&gt;8&lt;/code&gt;?&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='c1'&gt;// Exemplo 2&lt;/span&gt;
&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;foo&lt;/span&gt;&lt;span class='p'&gt;(){&lt;/span&gt;
  &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;bar&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;

  &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;bar&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt;

  &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;bar&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='mi'&gt;8&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;foo&lt;/span&gt;&lt;span class='p'&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Dentro do escopo da função &lt;code&gt;foo&lt;/code&gt;, primeiro temos a definição da função &lt;code&gt;bar&lt;/code&gt; que já está no topo. Depois do &lt;code&gt;return&lt;/code&gt; temos uma outra definição de função com o nome de &lt;code&gt;bar&lt;/code&gt;. Apesar de aparecer ao fim do escopo, ela é &lt;em&gt;hoisted&lt;/em&gt; — vai para o topo antes da execução. Como ela é a segunda função com o mesmo nome, ela acaba por &lt;strong&gt;sobreescrever a primeira&lt;/strong&gt;, e o nome &lt;code&gt;bar&lt;/code&gt; acaba por fazer referência à segunda função.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Uma função pode ser declarada também como uma expressão, e quando declarada desta forma, ela obedece a regra de &lt;em&gt;hoisting&lt;/em&gt; de variável. Apenas seu nome será &lt;em&gt;hoisted&lt;/em&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='c1'&gt;// Exemplo 10&lt;/span&gt;
&lt;span class='nx'&gt;foo&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='c1'&gt;//=&amp;gt; TypeError&lt;/span&gt;
&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;foo&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;No exemplo acima — exemplo 10 — será disparado um erro do tipo &lt;code&gt;TypeError&lt;/code&gt;, nos avisando que &lt;code&gt;undefined&lt;/code&gt; não pode ser usado como uma função.&lt;/p&gt;

&lt;h2 id=&quot;ecmascript_6&quot;&gt;ECMAScript 6&lt;/h2&gt;

&lt;p&gt;O ECMAScript 6 introduz um novo meio de definir variáveis através do &lt;code&gt;let&lt;/code&gt;. Com ele nós temos escopo a nível de bloco. No exemplo 11 temos um trecho de código extraído da &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let&quot;&gt;MDN&lt;/a&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='c1'&gt;// Exemplo 11&lt;/span&gt;
&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;varTest&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;x&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;31&lt;/span&gt;
  &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kc'&gt;true&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;x&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;71&lt;/span&gt; &lt;span class='c1'&gt;// mesma variável&lt;/span&gt;
    &lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='c1'&gt;// 71&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
  &lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='c1'&gt;// 71&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;letTest&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='kd'&gt;let&lt;/span&gt; &lt;span class='nx'&gt;x&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;31&lt;/span&gt;
  &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kc'&gt;true&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='kd'&gt;let&lt;/span&gt; &lt;span class='nx'&gt;x&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;71&lt;/span&gt; &lt;span class='c1'&gt;// variável diferente&lt;/span&gt;
    &lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='c1'&gt;// 71&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
  &lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='c1'&gt;// 31&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Com o &lt;code&gt;let&lt;/code&gt;, é criado um diferente escopo também dentro de blocos como &lt;code&gt;if&lt;/code&gt;, &lt;code&gt;for&lt;/code&gt;, &lt;code&gt;while&lt;/code&gt;, etc.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Outra diferença com o uso do &lt;code&gt;let&lt;/code&gt; é que não temos &lt;em&gt;hoisting&lt;/em&gt;, ou seja, a declaração da variável não vai para o topo do escopo antes da execução do código.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='c1'&gt;// Exemplo 12&lt;/span&gt;
&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;fooLet&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;bar&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='c1'&gt;//=&amp;gt; ReferenceError&lt;/span&gt;
  &lt;span class='kd'&gt;let&lt;/span&gt; &lt;span class='nx'&gt;bar&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='nx'&gt;fooLet&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt;

&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;fooVar&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;bar&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='c1'&gt;//=&amp;gt; Undefined&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;bar&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='nx'&gt;fooVar&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;No exemplo 12 temos dois trechos de código, um deles declara a variável &lt;code&gt;bar&lt;/code&gt; com &lt;code&gt;var&lt;/code&gt;, o outro com &lt;code&gt;let&lt;/code&gt;. Quando usamos &lt;code&gt;let&lt;/code&gt; não há &lt;em&gt;hoisting&lt;/em&gt;, e então recebemos um &lt;code&gt;ReferenceError&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;protip&quot;&gt;Protip&lt;/h2&gt;

&lt;p&gt;Como dica para evitar comportamentos inesperados, declare todas suas variáveis — todas mesmo — no topo das funções, utilize apenas um único &lt;code&gt;var&lt;/code&gt; por escopo e habilite a &lt;em&gt;flag&lt;/em&gt; &lt;code&gt;onevar&lt;/code&gt; do &lt;a href=&quot;http://www.jshint.com&quot;&gt;JSHint&lt;/a&gt;.&lt;/p&gt;

    </content>
  </entry>
  
  <entry>
    <id>http://loopinfinito.com.br/2014/09/09/ecmascript-6-proxy</id>
    <title>ECMAScript 6 Proxy</title>
    <updated>2014-09-09T00:00:00-07:00</updated>
    <link href="http://loopinfinito.com.br/2014/09/09/ecmascript-6-proxy/" />
    <author>
      <name>Caio Gondim</name>
      <uri>http://twitter.com/caio_gondim</uri>
    </author>
    <content type="html">
      
      
      &lt;p&gt;&lt;img itemprop=&quot;thumbnailUrl&quot; src=&quot;http://loopinfinito.com.br/images/posts/2014-09-09-ecmascript-6-proxy.jpg&quot; alt=&quot;ECMAScript 6 Proxy&quot; title=&quot;ECMAScript 6 Proxy&quot; width=&quot;700&quot; height=&quot;432&quot; /&gt;&lt;/p&gt;
      
      
&lt;p&gt;O termo &lt;em&gt;proxy&lt;/em&gt; tem suas origens no Direito dos países de língua inglesa. Um &lt;em&gt;proxy&lt;/em&gt; é alguém com poderes legais de representar uma outra pessoa. No Brasil seria algo como alguém que possui uma procuração para representar uma outra. Por analogia, o termo acabou sendo usado na computação para designar &lt;em&gt;softwares&lt;/em&gt; que atuam por outros como, por exemplo, um &lt;a href=&quot;http://en.wikipedia.org/wiki/Proxy_server&quot;&gt;Web Proxy&lt;/a&gt;, que funciona como um intermediário para requisições de um cliente a um servidor externo.&lt;/p&gt;

&lt;p&gt;No ECMAScript 6, um &lt;em&gt;proxy&lt;/em&gt; é um objeto que &lt;strong&gt;representa&lt;/strong&gt; um outro. Ele é capaz de interceptar chamadas às propriedades do objeto alvo, podendo até mesmo alterar o resultado da chamada.&lt;/p&gt;

&lt;h2 id=&quot;show_me_the_code&quot;&gt;Show me the code&lt;/h2&gt;

&lt;p&gt;Para melhor entender, vamos utilizar um exemplo simples.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;Pessoa&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;nome&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;idade&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;nome&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;nome&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;idade&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;idade&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;joao&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Pessoa&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;João&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;37&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;joao&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;idade&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='c1'&gt;//=&amp;gt; 37&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Acima criamos uma função construtora &lt;code&gt;Pessoa&lt;/code&gt; e logo após instanciamos um objeto do tipo &lt;code&gt;Pessoa&lt;/code&gt;. Checamos sua idade com &lt;code&gt;console.log&lt;/code&gt; e temos o resultado esperado: &lt;code&gt;37&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Agora vamos usar um &lt;em&gt;Proxy&lt;/em&gt; para interceptar chamadas à propriedade &lt;code&gt;idade&lt;/code&gt; do objeto &lt;code&gt;joao&lt;/code&gt;:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;proxy&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Proxy&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;joao&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;get&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;target&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;prop&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;prop&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;idade&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Acesso a prop. idade interceptado&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;

    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;target&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;prop&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Vamos passo-a-passo no código acima. O construtor de um &lt;em&gt;proxy&lt;/em&gt; aceita dois argumentos: o primeiro é o &lt;code&gt;target&lt;/code&gt; — o objeto que queremos interceptar as chamadas — o segundo é um objeto, que chamaremos por &lt;code&gt;handler&lt;/code&gt;, que define o comportamento do &lt;em&gt;proxy&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;As chaves do objeto &lt;code&gt;handler&lt;/code&gt; são chamadas de &lt;em&gt;traps&lt;/em&gt; — ou armadilhas — com os valores sendo funções que definem como o &lt;em&gt;proxy&lt;/em&gt; irá se comportar quando esta &lt;em&gt;trap&lt;/em&gt; for disparada.&lt;/p&gt;

&lt;p&gt;Acima usamos apenas a &lt;em&gt;trap&lt;/em&gt; &lt;code&gt;get&lt;/code&gt;, que é disparada quando tentamos ler uma propriedade do &lt;code&gt;target&lt;/code&gt; — o objeto que está sendo interceptado. Vamos discutir mais a fundo sobre todas as &lt;em&gt;traps&lt;/em&gt; logo.&lt;/p&gt;

&lt;p&gt;Também é possível utilizar o &lt;em&gt;proxy&lt;/em&gt; não apenas como intermediário, mas também como única porta de entrada para o objeto alvo, de forma transparente. Para isso, basta armazenar na variável que faz referência ao objeto alvo a própria referência ao &lt;em&gt;proxy&lt;/em&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;joao&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;idade&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='c1'&gt;//=&amp;gt; 37&lt;/span&gt;

&lt;span class='nx'&gt;joao&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;proxy&lt;/span&gt;
&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;joao&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;idade&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='c1'&gt;//=&amp;gt; Acesso a prop. idade interceptado&lt;/span&gt;
                        &lt;span class='c1'&gt;//=&amp;gt; 37&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Sendo assim, todo código que fazia referência à variável &lt;code&gt;joao&lt;/code&gt; passará agora pelo &lt;em&gt;proxy&lt;/em&gt; e este irá interceptar as chamadas ao objeto sem que seja alterado nenhum código antigo.&lt;/p&gt;

&lt;h2 id=&quot;aplicaes&quot;&gt;Aplicações&lt;/h2&gt;

&lt;p&gt;Por ser uma &lt;abbr title='Application programming interface'&gt;API&lt;/abbr&gt; muito nova, a comunidade ainda há de criar os melhores &lt;em&gt;cases&lt;/em&gt; de uso dessa nova &lt;em&gt;feature&lt;/em&gt; do JavaScript. Porém, alguns cenários já se mostram ideais para a aplicação dos &lt;em&gt;proxies&lt;/em&gt;.&lt;/p&gt;

&lt;h3 id=&quot;validao&quot;&gt;Validação&lt;/h3&gt;

&lt;p&gt;Podemos usar a armadilha &lt;code&gt;set&lt;/code&gt; para validarmos o novo valor de uma propriedade do objeto alvo. Caso seja um valor inválido, disparamos um erro e o valor não é alterado.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;joao&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Proxy&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;joao&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;set&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;target&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;prop&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;val&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='c1'&gt;// Verifica se estamos acessando a propriedade `idade` do obj. alvo&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;prop&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;idade&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;val&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;parseInt&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;val&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;10&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

      &lt;span class='c1'&gt;// Verifica se o novo valor é um inteiro&lt;/span&gt;
      &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;isNaN&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;val&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='nb'&gt;isFinite&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;val&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='k'&gt;throw&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;TypeError&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Idade deve ser um inteiro&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='p'&gt;}&lt;/span&gt;

      &lt;span class='c1'&gt;// Verifica se o novo valor é igual ou maior que 0&lt;/span&gt;
      &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;val&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='k'&gt;throw&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;RangeError&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Idade deve ser igual ou maior que 0&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='p'&gt;}&lt;/span&gt;

      &lt;span class='c1'&gt;// Verifica se o novo valor é menor que 200&lt;/span&gt;
      &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;val&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;=&lt;/span&gt; &lt;span class='mi'&gt;200&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='k'&gt;throw&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;RangeError&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Idade deve ser menor que 200&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='p'&gt;}&lt;/span&gt;

      &lt;span class='c1'&gt;// Comportamento padrão para armazenar o novo valor&lt;/span&gt;
      &lt;span class='nx'&gt;target&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;prop&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;val&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;})&lt;/span&gt;

&lt;span class='nx'&gt;joao&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;idade&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Uma string&amp;quot;&lt;/span&gt; &lt;span class='c1'&gt;// Irá disparar o erro `TypeError`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Neste exemplo estamos validando se a idade é:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Um número inteiro&lt;/li&gt;

&lt;li&gt;Maior ou igual a zero&lt;/li&gt;

&lt;li&gt;Menor que 200&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Perceba que a validação ocorre de forma transparente. Não é usado nenhum método &lt;code&gt;setIdade&lt;/code&gt; ou outro método que funciona de intermediário de forma explícita.&lt;/p&gt;

&lt;h3 id=&quot;log&quot;&gt;Log&lt;/h3&gt;

&lt;p&gt;Com um &lt;em&gt;proxy&lt;/em&gt; fica fácil criar uma função que recebe um objeto, intercepta e loga todos os acessos às suas propriedades.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;loggable&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;target&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;target&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt;  &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Proxy&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;target&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='c1'&gt;// Armadilha de acesso a propriedades&lt;/span&gt;
    &lt;span class='nx'&gt;get&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;target&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;prop&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;Lendo prop. &amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;prop&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;target&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;prop&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;
    &lt;span class='p'&gt;},&lt;/span&gt;

    &lt;span class='c1'&gt;// Armadilha de modificação de propriedades&lt;/span&gt;
    &lt;span class='nx'&gt;set&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;target&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;prop&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;val&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;Mudando valor da prop. &amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;prop&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39; para &amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;val&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='nx'&gt;target&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;prop&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;val&lt;/span&gt;
    &lt;span class='p'&gt;},&lt;/span&gt;

    &lt;span class='c1'&gt;// Armadilha de deleção de propriedades&lt;/span&gt;
    &lt;span class='nx'&gt;deleteProperty&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;target&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;prop&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;Deletando prop. &amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;prop&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='k'&gt;delete&lt;/span&gt; &lt;span class='nx'&gt;target&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;prop&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
  &lt;span class='p'&gt;})&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;joao&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Pessoa&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;João&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;37&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='c1'&gt;// Loga o acesso a todas as propriedades do objeto `joao`&lt;/span&gt;
&lt;span class='nx'&gt;loggable&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;joao&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

&lt;span class='nx'&gt;joao&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;idade&lt;/span&gt; &lt;span class='c1'&gt;//=&amp;gt; Lendo prop. idade&lt;/span&gt;
&lt;span class='nx'&gt;joao&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;idade&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;38&lt;/span&gt; &lt;span class='c1'&gt;//=&amp;gt; Mudando valor da prop. idade para 38. Era 37&lt;/span&gt;
&lt;span class='k'&gt;delete&lt;/span&gt; &lt;span class='nx'&gt;joao&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;idade&lt;/span&gt; &lt;span class='c1'&gt;//=&amp;gt; Deletada prop. idade&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;No exemplo acima criamos uma função &lt;code&gt;loggable&lt;/code&gt; que recebe um objeto como argumento e retorna um &lt;em&gt;proxy&lt;/em&gt; que imprime na saída padrão todo o acesso, mudança e deleção de propriedades do objeto interceptado.&lt;/p&gt;

&lt;h2 id=&quot;armadilhas&quot;&gt;Armadilhas&lt;/h2&gt;

&lt;p&gt;Abaixo, uma lista com algumas das armadilhas que achei mais úteis. Vale lembrar que existem outras além das que estão listadas abaixo. Uma documentação atualizada e completa sobre armadilhas nos &lt;em&gt;proxies&lt;/em&gt; pode ser vista na &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy#Validation&quot;&gt;Mozilla Developer Network&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;get&quot;&gt;Get&lt;/h3&gt;

&lt;p&gt;Disparada quando se tenta acessar uma propriedade no objeto alvo. A assinatura do &lt;em&gt;handler&lt;/em&gt; é a seguinte: &lt;code&gt;get function(target, name, receiver) -&amp;gt; any&lt;/code&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;foo&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;bar&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='nx'&gt;foo&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Proxy&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;foo&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;get&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;target&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;name&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;receiver&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='c1'&gt;// Seu código aqui...&lt;/span&gt;

    &lt;span class='c1'&gt;// Comportamento padrão de acesso a propriedade&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;target&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;name&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;})&lt;/span&gt;

&lt;span class='nx'&gt;foo&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;bar&lt;/span&gt; &lt;span class='c1'&gt;// Armadilha `get` será disparada nesta linha&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;set&quot;&gt;Set&lt;/h3&gt;

&lt;p&gt;Disparada quando se tenta trocar o valor de uma propriedade do objeto alvo. A assinatura do &lt;em&gt;handler&lt;/em&gt; é: &lt;code&gt;set function(target, name, val, receiver) -&amp;gt; boolean&lt;/code&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;foo&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{}&lt;/span&gt;

&lt;span class='nx'&gt;foo&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Proxy&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;foo&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;set&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;target&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;name&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;val&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;receiver&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='c1'&gt;// Seu código aqui...&lt;/span&gt;

    &lt;span class='c1'&gt;// Comportamento padrão&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;target&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;name&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;val&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;has&quot;&gt;Has&lt;/h3&gt;

&lt;p&gt;Disparado quando é verificado se uma propriedade existe no objeto alvo através do código &lt;code&gt;prop in proxy&lt;/code&gt;. A assinatura do &lt;em&gt;handler&lt;/em&gt; é: &lt;code&gt;has function(target, name) -&amp;gt; boolean&lt;/code&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;foo&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;bar&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='nx'&gt;foo&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Proxy&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;foo&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;has&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;target&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;name&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='c1'&gt;// Comportamento padrão&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;name&lt;/span&gt; &lt;span class='k'&gt;in&lt;/span&gt; &lt;span class='nx'&gt;target&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;enumerate&quot;&gt;Enumerate&lt;/h3&gt;

&lt;p&gt;Retorna um &lt;em&gt;array&lt;/em&gt; de &lt;em&gt;string&lt;/em&gt; com o nomes das propriedades que devem ser lidas em um &lt;em&gt;loop&lt;/em&gt; &lt;code&gt;for in&lt;/code&gt;. A assinatura do &lt;em&gt;handler&lt;/em&gt;: &lt;code&gt;enumerate function(target) -&amp;gt; [String]&lt;/code&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;foo&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;lorem&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;ipsum&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='nx'&gt;foo&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;Proxy&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;foo&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;enumerate&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nx'&gt;funtion&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;target&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;lorem&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;})&lt;/span&gt;

&lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;prop&lt;/span&gt; &lt;span class='k'&gt;in&lt;/span&gt; &lt;span class='nx'&gt;foo&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='c1'&gt;// irá iterar apenas na propriedade `lorem`&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table class='support'&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th class='subject'&gt;&lt;h2&gt;Suporte&lt;/h2&gt;&lt;/th&gt;
      &lt;th class='browser chrome'&gt;&lt;div class='i' /&gt;&lt;/th&gt;
      &lt;th class='browser safari'&gt;&lt;div class='i' /&gt;&lt;/th&gt;
      &lt;th class='browser firefox'&gt;&lt;div class='i' /&gt;&lt;/th&gt;
      &lt;th class='browser ie'&gt;&lt;div class='i' /&gt;&lt;/th&gt;
      &lt;th class='browser opera'&gt;&lt;div class='i' /&gt;&lt;/th&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th /&gt;
      &lt;th class='base' colspan='5' /&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td class='property'&gt;Proxy&lt;/td&gt;
      &lt;td&gt;*&lt;/td&gt;
      &lt;td&gt;--&lt;/td&gt;
      &lt;td&gt;32&lt;/td&gt;
      &lt;td&gt;--&lt;/td&gt;
      &lt;td&gt;--&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
  &lt;tfoot&gt;
    &lt;tr&gt;&lt;td colspan='6'&gt;* implementado, porém na antiga especificação&lt;/td&gt;&lt;/tr&gt;
  &lt;/tfoot&gt;
&lt;/table&gt;
&lt;p&gt;Agora as más notícias. Atualmente a última versão da Proxy &lt;abbr title='Application programming interface'&gt;API&lt;/abbr&gt; definida no ECMAScript 6 só está disponível no Firefox. No V8, a máquina virtual de JavaScript do Chrome e Node.js, ela também está presente, porém está implementada conforme a definição antiga. Entretanto é possível usar um &lt;em&gt;shim&lt;/em&gt;, como o &lt;a href=&quot;https://github.com/Swatinem/proxy&quot;&gt;harmony proxy&lt;/a&gt;, para normalizar a antiga &lt;abbr title='Application programming interface'&gt;API&lt;/abbr&gt; com a nova no Chrome e Node.js.&lt;/p&gt;

&lt;p&gt;Para mais informações sobre compatibilidade do ECMAScript 6 com os mais populares ambientes JavaScripts, aconselho uma visita na &lt;a href=&quot;http://kangax.github.io/compat-table/es6/&quot;&gt;tabela de compatibilidade&lt;/a&gt; do &lt;a href=&quot;https://twitter.com/kangax&quot;&gt;kangax&lt;/a&gt;.&lt;/p&gt;

    </content>
  </entry>
  
  <entry>
    <id>http://loopinfinito.com.br/2014/07/22/a-metafora-do-escritorio</id>
    <title>A metáfora do escritório</title>
    <updated>2014-07-22T00:00:00-07:00</updated>
    <link href="http://loopinfinito.com.br/2014/07/22/a-metafora-do-escritorio/" />
    <author>
      <name>Caio Gondim</name>
      <uri>http://twitter.com/caio_gondim</uri>
    </author>
    <content type="html">
      
      
      &lt;p&gt;&lt;img itemprop=&quot;thumbnailUrl&quot; src=&quot;http://loopinfinito.com.br/images/posts/2014-07-22-a-metafora-do-escritorio.png&quot; alt=&quot;A metáfora do escritório&quot; title=&quot;A metáfora do escritório&quot; width=&quot;700&quot; height=&quot;432&quot; /&gt;&lt;/p&gt;
      
      &lt;style&gt;
  .video-youtube-embed {
    margin-left: -50px;
    width: 700px;
    height: 432px;
  }
&lt;/style&gt;
&lt;p&gt;Usar um computador nem sempre foi uma tarefa fácil — não que hoje o seja. Computadores eram telas pretas com letras verdes. Máquinas que executavam uma única tarefa por vez a partir da entrada de comandos no &lt;em&gt;terminal&lt;/em&gt;. Comandos esses difíceis de serem decorados e quase impossíveis de serem deduzidos.&lt;/p&gt;

&lt;p&gt;Por volta de 1960, computadores começavam a ganhar alguma popularidade fora das empresas, principalmente entre grupos de &lt;em&gt;hobbistas&lt;/em&gt;. Pessoas essas que gastavam um bom tempo lendo grossos manuais para só então serem capaz de interagir com um computador. Toda essa complexidade assustava a maioria das pessoas e era, obviamente, um grande empecilho para a popularização destas fantásticas máquinas.&lt;/p&gt;

&lt;p&gt;Era necessário uma mudança radical no modo de interagir com um computador. Algo mais visual, mais próximo da realidade de um ser humano e mais distante da realidade baixo nível de uma máquina. Porém, a tecnologia necessária simplesmente não existia para tal quebra de paradigma.&lt;/p&gt;

&lt;h2 id=&quot;a_me_de_todos_os_demos&quot;&gt;A Mãe de Todos os Demos&lt;/h2&gt;

&lt;p&gt;Na ciência estamos sempre nos apoiando em ombros de gigantes. Com a invenção da Interface Gráfica não foi diferente. Não houve de fato um inventor, mas sim uma série de melhorias que foram feitas em cima da geração anterior.&lt;/p&gt;

&lt;p&gt;Um dos primeiros teóricos sobre o assunto foi &lt;a href=&quot;http://en.wikipedia.org/wiki/Vannevar_Bush&quot;&gt;Vannevar Bush&lt;/a&gt;, engenheiro americano chefe do escritório &lt;em&gt;Office of Scientific Research and Development&lt;/em&gt; durante a segunda guerra mundial que, em 1945, publicou um artigo com o título &lt;a href=&quot;http://www.theatlantic.com/magazine/archive/1945/07/as-we-may-think/303881/&quot;&gt;“As We May Think”&lt;/a&gt; descrevendo sua visão do futuro de como usaríamos máquinas — chamadas por ele de &lt;strong&gt;Memex&lt;/strong&gt; — para acessar um vasto conjunto de dados ligados entre si (&lt;em&gt;linked data&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Este artigo serviu de inspiração para &lt;a href=&quot;http://en.wikipedia.org/wiki/Douglas_Engelbart&quot;&gt;Douglas Engelbart&lt;/a&gt;. Durante sua estadia na faculdade de Stanford, no Vale do Silício, ele formou o &lt;em&gt;Augmentation Research Center&lt;/em&gt; e lá concebeu algumas das invenções bases para a &lt;abbr title='Graphical User Interface'&gt;GUI&lt;/abbr&gt; ser o que é hoje. Entre essas invenções estava o &lt;em&gt;mouse&lt;/em&gt;, um dispositivo que permitia mover um ponteiro através da tela e manipular informação de uma maneira mais flexível e natural.&lt;/p&gt;

&lt;p&gt;&lt;q class='pushing-quotes'&gt;
  The digital revolution is &lt;strong&gt;far more significant&lt;/strong&gt;than the invention of writing or even of printing — Douglas Engelbart&lt;/q&gt;&lt;/p&gt;

&lt;p&gt;Em dezembro de 1968, em San Francisco, Douglas Engelbart demonstrara todas as novas invenções feitas por sua equipe. Entre essas invenções estava o já citado &lt;em&gt;mouse&lt;/em&gt; e também o conceito de janelas, hipertexto, gráficos, vídeo conferência, processador de texto, controle de versão e um editor de texto colaborativo. Essa apresentação foi — e é — um marco na história da computação, e ficou conhecida como &lt;strong&gt;A Mãe de Todos os Demos&lt;/strong&gt;, a demonstração mais fantástica e à frente de seu tempo da área. Ela pode ser — e deveria ser — vista completa &lt;a href=&quot;http://www.youtube.com/watch?v=yJDv-zdhzMY&quot;&gt;aqui&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;parc&quot;&gt;PARC&lt;/h2&gt;

&lt;p&gt;A próxima onda de inovação no campo das Interfaces Gráficas do Usuário aconteceria em Palo Alto, no lendário laboratório PARC (Palo Alto Research Center) da Xerox, onde, em 1970, boa parte da equipe de Engelbart foi trabalhar. Lá refinaram suas ideias e inclusive conseguiram implementar e comercializar estas novas ideias, em 1981, com o computador &lt;a href=&quot;http://en.wikipedia.org/wiki/Xerox_Star&quot;&gt;Xerox Star&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt='Xerox Alto' src='http://loopinfinito.com.br/images/posts/2014-07-22-xerox-alto.jpg' width='700' /&gt;
&lt;/figure&gt;
&lt;p&gt;O Xerox Star foi o primeiro computador comercial a vir com uma interface gráfica do usuário baseada em janelas (&lt;em&gt;windows&lt;/em&gt;), ícones, pastas, um &lt;em&gt;mouse&lt;/em&gt;, rede ethernet, servidor de arquivos, servidor de impressão e e-mail.&lt;/p&gt;

&lt;p&gt;Ele foi, também, o primeiro computador a empregar a técnica de &lt;em&gt;bit mapping&lt;/em&gt;. Em essência, tudo na tela do Xerox Star era uma imagem. A técnica de &lt;em&gt;bit mapping&lt;/em&gt; tornou mais simples o ato de se trabalhar com gráficos e também permitiu que o computador apresentasse na tela uma exata representação do que seria impresso. O que ficou conhecido como WYSIWYG (What You See Is What You Get).&lt;/p&gt;

&lt;p&gt;Muitos creditam a invenção das interfaces gráficas como conhecemos hoje ao PARC. Lá, eles não só criaram (refinaram) a GUI, como também inventaram a programação orientada a objetos — com a linguagem &lt;a href=&quot;http://pt.wikipedia.org/wiki/Smalltalk&quot;&gt;Smalltalk&lt;/a&gt; — o &lt;em&gt;design pattern&lt;/em&gt;  &lt;a href=&quot;http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller&quot;&gt;MVC&lt;/a&gt;, a impressora a laser, o ethernet, editores de texto WYSIWYG e tantas outras.&lt;/p&gt;

&lt;p&gt;Os cientistas do PARC definiram a base da Interface Gráfica do Usuário como sendo o WIMP, sigla para &lt;strong&gt;Windows, Icons, Menu and Pointer Device&lt;/strong&gt;. Até hoje, a maioria dos sistemas &lt;em&gt;desktops&lt;/em&gt;, entre eles Windows, OS X, Gnome, KDE, utilizam essa base.&lt;/p&gt;

&lt;p&gt;&lt;q class='pushing-quotes'&gt;
  The best way to predict the future is to &lt;strong&gt;invent it&lt;/strong&gt; — Alan Kay
&lt;/q&gt;&lt;/p&gt;

&lt;p&gt;Em cima desses elementos básicos, foi criada a Metáfora do Escritório. Os cientistas do PARC, principalmente &lt;a href=&quot;http://pt.wikipedia.org/wiki/Alan_Kay&quot;&gt;Alan Kay&lt;/a&gt;, decidiram usar metáforas a tarefas comuns em um escritório para diminuir a curva de aprendizado de uso de um computador.&lt;/p&gt;

&lt;h2 id=&quot;a_metfora&quot;&gt;A metáfora&lt;/h2&gt;

&lt;p&gt;A primeira &lt;em&gt;Graphical User Interface&lt;/em&gt;, ou GUI, era uma &lt;strong&gt;metáfora a um ambiente de escritório&lt;/strong&gt;. O desktop, ou área de trabalho, representava uma mesa de escritório. Em cima dela tínhamos papéis, que eram arquivos do computador.&lt;/p&gt;

&lt;p&gt;Estes mesmos arquivos podiam ser agrupados em pastas, assim como papéis são organizados em pastas nos escritórios. Os arquivos poderiam ser jogados em uma lixeira, tal qual, também, é feito em um escritório. Estes arquivos poderiam, inclusive, serem resgatados da lixeira, do mesmo modo que podemos fazer com um papel amassado jogado no lixo.&lt;/p&gt;

&lt;p&gt;Além da metáfora do escritório, foi desenvolvido o conceito de janelas. Cada janela representaria um aplicativo aberto. Cada aplicativo aberto seria o equivalente a um papel em uma mesa. Nele o trabalho aconteceria.&lt;/p&gt;

&lt;p&gt;A Apple foi uma das grandes responsáveis pela popularização da GUI. Steve Jobs em uma visita ao Xerox PARC conheceu a GUI, e logo percebeu que aquilo era o futuro. A Xerox estava com problemas para vender o Xerox Alto, o único computador que até então rodava com uma GUI. Jobs então fez uma proposta a Xerox para comprar a GUI, e implementar no que viria a ser o &lt;a href=&quot;http://pt.wikipedia.org/wiki/Apple_Lisa&quot;&gt;Apple Lisa&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;No vídeo abaixo temos uma propaganda de televisão da Apple, anunciando seu novo computador e a sua GUI com a metáfora do escritório como sendo um diferencial entre outros produtos da época, devido a sua facilidade de uso. Perceba como o ator usa o seu dedo como ponteiro, simulando um &lt;em&gt;mouse&lt;/em&gt;, apontando para objetos que o Mac simula em sua interface, como papéis, pastas e calculadora.&lt;/p&gt;
&lt;iframe class='video-youtube-embed' frameborder='0' src='http://www.youtube.com/embed/1UtlOgkOGy4'&gt;&amp;nbsp;&lt;/iframe&gt;
&lt;p&gt;Praticamente todos os sistemas operacionais que adotaram uma interface gráfica utilizaram ou utilizam a metáfora do escritório. Alguns mais puristas em relação a própria metáfora, outros mais práticos.&lt;/p&gt;

&lt;p&gt;O &lt;a href=&quot;http://en.wikipedia.org/wiki/BeOS&quot;&gt;BeOS&lt;/a&gt;, por exemplo, mostrava um ícone de dispositivos externos conectados no desktop, enquanto que dispositivos internos eram acessados através do ícone do computador, para ser mais fiel a metáfora.&lt;/p&gt;

&lt;p&gt;Uma das implementações mais fiéis à metáfora em si veio em 2010 com o BumpTop. A ideia da interface do BumpTop era de simular de forma mais real uma mesa de trabalho de escritório. Nele, os documentos são pequenos objetos 3D que podem ser empilhados, manipulados usando gestos e, inclusive, jogados de um lado para o outro utilizando leis físicas para uma experiência mais realista.&lt;/p&gt;
&lt;iframe class='video-youtube-embed' frameborder='0' src='http://www.youtube.com/embed/M0ODskdEPnQ'&gt;&amp;nbsp;&lt;/iframe&gt;
&lt;p&gt;Infelizmente, o produto BumpTop foi descontinuado logo após a empresa ter sido comprada pelo Google.&lt;/p&gt;

&lt;h2 id=&quot;impactos&quot;&gt;Impactos&lt;/h2&gt;

&lt;p&gt;A Metáfora do Desktop desenvolvida pela equipe de Alan Kay é até hoje usada em todos os grandes sistemas operacionais de desktop. Ela foi um importante passo para que computadores ganhassem a popularidade que hoje possuem. Tornou possível o uso de computadores por pessoas não técnicas e abriu diferentes possibilidades na criação de programas de computadores, já que não estávamos mais limitados a uma interface de linha de comando.&lt;/p&gt;

&lt;p&gt;Ela é hoje tão popular que, para muitos, superou sua “inspiração”. Quando falamos de pastas ou arquivos, logo nos vem a cabeça não mais pastas e vários papéis, mas sim arquivos e pastas em um computador. O próprio nome &lt;em&gt;desktop&lt;/em&gt; é, hoje, mais relacionado a sua área de trabalho no computador do que a sua mesa de trabalho em um escritório.&lt;/p&gt;

    </content>
  </entry>
  
  <entry>
    <id>http://loopinfinito.com.br/2014/06/19/o-grande-encontro-do-html-com-o-http</id>
    <title>O grande encontro do HTML com o HTTP</title>
    <updated>2014-06-19T00:00:00-07:00</updated>
    <link href="http://loopinfinito.com.br/2014/06/19/o-grande-encontro-do-html-com-o-http/" />
    <author>
      <name>Almir Filho</name>
      <uri>http://twitter.com/almirfilho</uri>
    </author>
    <content type="html">
      
      
      &lt;p&gt;&lt;img itemprop=&quot;thumbnailUrl&quot; src=&quot;http://loopinfinito.com.br/images/posts/2014-06-19-o-grande-encontro-do-html-com-o-http.jpg&quot; alt=&quot;O grande encontro do HTML com o HTTP&quot; title=&quot;O grande encontro do HTML com o HTTP&quot; width=&quot;700&quot; height=&quot;432&quot; /&gt;&lt;/p&gt;
      
      
&lt;p&gt;Li um &lt;a href=&quot;http://tableless.com.br/o-grande-desencontro-http-com-o-html/&quot; title=&quot;O grande desencontro do HTTP com o HTML&quot;&gt;&lt;em&gt;post&lt;/em&gt; muito bom&lt;/a&gt; do &lt;a href=&quot;https://twitter.com/jcemer&quot; title=&quot;Jean Carlo Emer (twitter)&quot;&gt;@jcemer&lt;/a&gt; que aborda os problemas de inconsistência entre o &lt;abbr title='HyperText Markup Language'&gt;HTML&lt;/abbr&gt; e o &lt;abbr title='HyperText Transfer Protocol'&gt;HTTP&lt;/abbr&gt;. O artigo menciona, inclusive, um rascunho do editor que propunha melhorias ao que se diz respeito às capacidades dos formulários web de realizar tarefas consideradas bem comuns hoje em dia, mas que dependem de JavaScript e de outras técnicas comuns que viabilizem seus usos. Algumas dessas técnicas foram desenvolvidas com o intuito de suprir algumas questões divergentes entre o HTML e o HTTP, sobretudo quando se deseja utilizar &lt;abbr title='Representational State Transfer'&gt;REST&lt;/abbr&gt; — como por exemplo o uso dos métodos &lt;code&gt;PUT&lt;/code&gt; e &lt;code&gt;DELETE&lt;/code&gt; diretamente no atributo &lt;code&gt;method&lt;/code&gt; do &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Para entender plenamente do que se tratam esses problemas, recomendo a leitura do &lt;a href=&quot;http://tableless.com.br/o-grande-desencontro-http-com-o-html/&quot;&gt;post do Jean&lt;/a&gt; — o qual inspirou o título deste.&lt;/p&gt;

&lt;h2 id=&quot;a_motivao&quot;&gt;A motivação&lt;/h2&gt;

&lt;p&gt;Uns dias depois do &lt;em&gt;post&lt;/em&gt; do Jean, me deparei com o seguinte &lt;a href=&quot;https://twitter.com/w3c/statuses/472032014942879744&quot;&gt;&lt;em&gt;tweet&lt;/em&gt;&lt;/a&gt; do &lt;a href=&quot;https://twitter.com/w3c&quot;&gt;@W3C&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote class='twitter-tweet' lang='en'&gt;
    &lt;p&gt;
    First Public Working Drafts: W3C HTML Form HTTP Extensions, W3C HTML JSON
    Form Submission &lt;a href='http://t.co/CDF0LPl0Ve'&gt;http://t.co/CDF0LPl0Ve&lt;/a&gt;
    &lt;/p&gt;
    &amp;mdash; W3C (@w3c)
    &lt;a href='https://twitter.com/w3c/statuses/472032014942879744'&gt;May 29, 2014&lt;/a&gt;
&lt;/blockquote&gt;&lt;script async='async' charset='utf-8' src='//platform.twitter.com/widgets.js'&gt; &lt;/script&gt;
&lt;p&gt;O &lt;a href=&quot;http://cameronjones.github.io/form-http-extensions/index.html#form-method-attribute&quot;&gt;rascunho do editor&lt;/a&gt; evoluiu para um &lt;a href=&quot;http://www.w3.org/TR/form-http-extensions/&quot; title=&quot;W3C HTML Form HTTP Extensions&quot;&gt;rascunho público do W3C&lt;/a&gt;, ou seja, parece que a coisa vai rolar mesmo — então decidi dar uma estudada na proposta e falar um pouco sobre o que achei mais legal. Será esse o encontro definitivo entre o HTML e seu protocolo de transferência?&lt;/p&gt;

&lt;h2 id=&quot;html__forms&quot;&gt;HTML ♥ Forms&lt;/h2&gt;

&lt;p&gt;As propostas desse rascunho não se referem somente a entrar em conformidade com os verbos REST. Há recursos para padronizar autenticação HTTP e até mesmo para enviar informações diretamente no &lt;em&gt;header&lt;/em&gt; de uma submissão de formulário.&lt;/p&gt;

&lt;h2 id=&quot;mtodos_http&quot;&gt;Métodos HTTP&lt;/h2&gt;

&lt;p&gt;Será possível especificar quase todos os métodos HTTP através do atributo &lt;code&gt;method&lt;/code&gt; de um formulário. Atualmente apenas são suportados os métodos &lt;code&gt;GET&lt;/code&gt; e &lt;code&gt;POST&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;O HTTP tem 9 métodos, e os únicos que &lt;strong&gt;não&lt;/strong&gt; poderão ser utilizados são &lt;code&gt;CONNECT&lt;/code&gt;, &lt;code&gt;TRACE&lt;/code&gt; e &lt;code&gt;TRACK&lt;/code&gt;. Claro que, os que saltam aos olhos são os já utilizados no padrão REST — os métodos &lt;code&gt;PUT&lt;/code&gt; e &lt;code&gt;DELETE&lt;/code&gt;. Quanto aos restantes, consigo imaginar uma utilidade para &lt;code&gt;HEAD&lt;/code&gt; e &lt;code&gt;PATCH&lt;/code&gt;, mas não para &lt;code&gt;OPTION&lt;/code&gt; — e também não há exemplos de utilização desses métodos no documento do W3C (por enquanto).&lt;/p&gt;

&lt;p&gt;Como mostrado no &lt;a href=&quot;http://tableless.com.br/o-grande-desencontro-http-com-o-html/&quot;&gt;&lt;em&gt;post&lt;/em&gt; do @jcemer&lt;/a&gt;, os &lt;em&gt;frameworks&lt;/em&gt; geralmente utilizam campos &lt;code&gt;&amp;lt;input type=&amp;quot;hidden&amp;quot;&amp;gt;&lt;/code&gt; para poder especificar métodos que não são &lt;code&gt;GET&lt;/code&gt; nem &lt;code&gt;POST&lt;/code&gt; e daí realizar as gambiarras necessárias no lado do servidor. Imagino que agora as coisas vão ficar um pouco mais simples.&lt;/p&gt;

&lt;h3 id=&quot;methodput&quot;&gt;method=“PUT”&lt;/h3&gt;

&lt;p&gt;O método &lt;code&gt;PUT&lt;/code&gt;, como já sabemos, serve para atualizar um objeto/recurso no servidor.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='html'&gt;&lt;span class='nt'&gt;&amp;lt;form&lt;/span&gt; &lt;span class='na'&gt;action=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;http://ego.globo.com/noticias/1440&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;method=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;PUT&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;input&lt;/span&gt; &lt;span class='na'&gt;type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;text&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;titulo&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;value=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;Daniel Filho aparou a barba.&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;textarea&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;conteudo&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
        Daniel Filho finalmente criou vergonha na cara e (...)
    &lt;span class='nt'&gt;&amp;lt;/textarea&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;button&lt;/span&gt; &lt;span class='na'&gt;type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;submit&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;Atualizar&lt;span class='nt'&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;No trecho acima, temos um formulário que atualiza uma notícia (de alto grau de importância) com identificador “1440” do &lt;a href=&quot;http://ego.globo.com&quot;&gt;portal ego&lt;/a&gt; (super relevante para nossas vidas #sqn).&lt;/p&gt;
&lt;p class='obs'&gt;
    &lt;strong&gt;Obs.:&lt;/strong&gt; Não mostrem isso ao Daniel. Ele nem vai ler esse post
    mesmo. =P
&lt;/p&gt;
&lt;h3 id=&quot;methoddelete&quot;&gt;method=“DELETE”&lt;/h3&gt;

&lt;p&gt;Com o método &lt;code&gt;DELETE&lt;/code&gt; podemos deletar um objeto/recurso (dãã).&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='html'&gt;&lt;span class='nt'&gt;&amp;lt;form&lt;/span&gt; &lt;span class='na'&gt;action=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;http://ego.globo.com/noticias&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;method=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;DELETE&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;button&lt;/span&gt; &lt;span class='na'&gt;type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;submit&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;Excluir&lt;span class='nt'&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;No trecho acima, temos um formulário que provê um &lt;strong&gt;grande serviço à humanidade&lt;/strong&gt;, mandando todas as notícias do portal ego &lt;em&gt;pro raio que o parta&lt;/em&gt; com o simples uso do método &lt;code&gt;DELETE&lt;/code&gt; (acho que esse método nunca foi tão bem utilizado, hein). Claro que o serviço em questão deve estar em conformidade com o padrão REST para que isso aconteça.&lt;/p&gt;

&lt;h2 id=&quot;atributo_payload&quot;&gt;Atributo payload&lt;/h2&gt;

&lt;p&gt;O atributo &lt;code&gt;payload&lt;/code&gt; é usado para representar a associação entre um determinado dado (ou campo) de um formulário a um tipo de esquema de dados (&lt;code&gt;http&lt;/code&gt;/&lt;code&gt;https&lt;/code&gt;/&lt;code&gt;data&lt;/code&gt;/&lt;code&gt;mailto&lt;/code&gt;) na submissão do formulário. Um &lt;em&gt;payload&lt;/em&gt; pode ser basicamente de três tipos: &lt;strong&gt;action&lt;/strong&gt;, &lt;strong&gt;header&lt;/strong&gt; ou &lt;strong&gt;body&lt;/strong&gt; (valores &lt;code&gt;_action&lt;/code&gt;, &lt;code&gt;_header&lt;/code&gt; e &lt;code&gt;_body&lt;/code&gt; respectivamente).&lt;/p&gt;

&lt;h3 id=&quot;payloadaction&quot;&gt;payload=“&lt;em&gt;action“&lt;/em&gt;&lt;/h3&gt;

&lt;p&gt;Informação ou dado que descreve uma ação a ser executada no lado do servidor. Comumente referente ao atributo &lt;code&gt;action&lt;/code&gt; do formulário.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='html'&gt;&lt;span class='nt'&gt;&amp;lt;form&lt;/span&gt; &lt;span class='na'&gt;action=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;mailto:&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;input&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;to&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;email&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;payload=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;_action&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;textarea&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;content&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
        Parabéns Daniel Filho! Você foi contemplado com um barbeador (...)
    &lt;span class='nt'&gt;&amp;lt;/textarea&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;button&lt;/span&gt; &lt;span class='na'&gt;type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;submit&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;Enviar email&lt;span class='nt'&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fiz esse exemplo acima com base no que existe no rascunho do W3C. Pelo que entendi, o &lt;code&gt;input[name=to]&lt;/code&gt; é associado à &lt;em&gt;action&lt;/em&gt; que descreve um endereço de &lt;em&gt;email&lt;/em&gt;, no entanto, não ficou claro como isso acontece exatamente. Por exemplo, se adicionarmos mais um &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; com &lt;code&gt;payload=&amp;quot;_action&amp;quot;&lt;/code&gt;, o que deverá acontecer? Seguindo a lógica do &lt;em&gt;action&lt;/em&gt;, informações adicionais seriam impostas na forma de &lt;em&gt;querystring&lt;/em&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='html'&gt;&lt;span class='nt'&gt;&amp;lt;form&lt;/span&gt; &lt;span class='na'&gt;action=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;http://ego.globo.com/noticias&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;method=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;PUT&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;input&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;id&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;hidden&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;payload=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;_action&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;value=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;1440&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class='c'&gt;&amp;lt;!-- ... --&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Isso faria sentido. Deixando assim a URL do recurso mais limpa, e especificando seus parâmetros em outros lugares. A &lt;code&gt;action&lt;/code&gt; resultante acima seria “http://ego.globo.com/noticias?id=1440”.&lt;/p&gt;

&lt;h3 id=&quot;payloadheader&quot;&gt;payload=“&lt;em&gt;header“&lt;/em&gt;&lt;/h3&gt;

&lt;p&gt;Informação que pode ser incluída no &lt;em&gt;header&lt;/em&gt; da submissão. Com isso pode-se especificar valores para um determinado &lt;em&gt;header&lt;/em&gt;. O exemplo a seguir envia o &lt;em&gt;header&lt;/em&gt; &lt;code&gt;If-Unmodified-Since&lt;/code&gt; na submissão do formulário.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='html'&gt;&lt;span class='nt'&gt;&amp;lt;form&lt;/span&gt; &lt;span class='na'&gt;action=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;http://ego.globo.com/noticias/1440&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;method=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;DELETE&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;input&lt;/span&gt; &lt;span class='na'&gt;type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;hidden&amp;quot;&lt;/span&gt;
           &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;If-Unmodified-Since&amp;quot;&lt;/span&gt;
           &lt;span class='na'&gt;value=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;Tue, 1 Jan 2013 12:00:00 GMT&amp;quot;&lt;/span&gt;
           &lt;span class='na'&gt;payload=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;_header&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;button&lt;/span&gt; &lt;span class='na'&gt;type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;submit&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;Excluir&lt;span class='nt'&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Só vai excluir o objeto se o mesmo não foi modificado desde a data especificada.&lt;/p&gt;

&lt;h3 id=&quot;payloadbody&quot;&gt;payload=“&lt;em&gt;body“&lt;/em&gt;&lt;/h3&gt;

&lt;p&gt;Dado que pertence ao conteúdo (&lt;em&gt;body&lt;/em&gt;) da submissão. É o valor padrão para a maioria dos casos.&lt;/p&gt;

&lt;h2 id=&quot;autenticao_http&quot;&gt;Autenticação HTTP&lt;/h2&gt;

&lt;p&gt;Outra ação bem comum realizada via formulários é o &lt;em&gt;login&lt;/em&gt; em algum serviço. &lt;em&gt;Logins&lt;/em&gt; geralmente necessitam de pelo menos duas informações, o identificador do usuário que está tentando acessar o sistema e sua senha — claro que estamos falando de autenticações simples aqui (antes que venham falar sobre OAuth). Da mesma maneira também há uma proposta para padronizar a ação de &lt;em&gt;logout&lt;/em&gt;.&lt;/p&gt;

&lt;h3 id=&quot;login&quot;&gt;Login&lt;/h3&gt;

&lt;p&gt;Para determinar que um formulário realize uma submissão de um &lt;em&gt;login&lt;/em&gt;, basta definir os elementos &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; de usuário e senha cada qual com seu atributo &lt;code&gt;name&lt;/code&gt; como &lt;code&gt;_username_&lt;/code&gt; e &lt;code&gt;_password_&lt;/code&gt;, respectivamente.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='html'&gt;&lt;span class='nt'&gt;&amp;lt;form&lt;/span&gt; &lt;span class='na'&gt;action=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;http://dandan.com/login&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;method=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;POST&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;label&lt;/span&gt; &lt;span class='na'&gt;for=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;usuario&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;Usuário&lt;span class='nt'&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;input&lt;/span&gt; &lt;span class='na'&gt;id=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;usuario&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;_username_&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;text&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;label&lt;/span&gt; &lt;span class='na'&gt;for=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;senha&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;Senha&lt;span class='nt'&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;input&lt;/span&gt; &lt;span class='na'&gt;id=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;senha&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;_password_&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;password&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;button&lt;/span&gt; &lt;span class='na'&gt;type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;submit&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;Entrar&lt;span class='nt'&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;_username_&lt;/code&gt;: Deve ser utilizado apenas em elementos &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; do tipo &lt;code&gt;text&lt;/code&gt; ou &lt;code&gt;email&lt;/code&gt;.&lt;/li&gt;

&lt;li&gt;&lt;code&gt;_password_&lt;/code&gt;: Deve ser utilizado apenas em elementos &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; do tipo &lt;code&gt;password&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tá, mas qual a real vantagem disso? Bem, se essa convenção for utilizada, então o agente de usuário (navegador) automaticamente deverá incluir um &lt;em&gt;header&lt;/em&gt; adequado de autorização na requisição, no caso, esse &lt;em&gt;header&lt;/em&gt; seria o &lt;code&gt;Authorization&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;logout&quot;&gt;Logout&lt;/h3&gt;

&lt;p&gt;A ação de &lt;em&gt;logout&lt;/em&gt; é mais simples ainda. Precisa-se apenas de um &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; do tipo &lt;code&gt;hidden&lt;/code&gt; com seu atributo &lt;code&gt;name=&amp;quot;_logout_&amp;quot;&lt;/code&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='html'&gt;&lt;span class='nt'&gt;&amp;lt;form&lt;/span&gt; &lt;span class='na'&gt;action=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;http://dandan.com/logout&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;method=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;POST&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;input&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;_logout_&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;hidden&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;button&lt;/span&gt; &lt;span class='na'&gt;type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;submit&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;Sair&lt;span class='nt'&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Isso deve fazer com que o agente de usuário (que suporte autenticação HTTP e que reutilize credenciais de &lt;em&gt;login&lt;/em&gt; em suas requisições) limpe quaisquer informações sobre credenciais de &lt;em&gt;login&lt;/em&gt; previamente armazenadas.&lt;/p&gt;

&lt;h2 id=&quot;curiosidades&quot;&gt;Curiosidades&lt;/h2&gt;

&lt;p&gt;Na minha pesquisa, encontrei algumas informações interessantes.&lt;/p&gt;

&lt;h3 id=&quot;put_e_delete_no_firefox&quot;&gt;PUT e DELETE no Firefox&lt;/h3&gt;

&lt;p&gt;A Mozilla chegou a implementar os métodos &lt;code&gt;PUT&lt;/code&gt; e &lt;code&gt;DELETE&lt;/code&gt; em formulários no Firefox 4 Beta (2011), mas depois foram removidos. &lt;a href=&quot;http://lists.w3.org/Archives/Public/public-html-comments/2011Mar/0007.html&quot;&gt;Fonte&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;put_e_delete_no_html5&quot;&gt;PUT e DELETE no HTML5&lt;/h3&gt;

&lt;p&gt;Os métodos &lt;code&gt;PUT&lt;/code&gt; e &lt;code&gt;DELETE&lt;/code&gt; chegaram a fazer parte de alguns &lt;a href=&quot;http://www.w3.org/TR/2010/WD-html5-20100624/association-of-controls-and-forms.html#attr-fs-method&quot;&gt;rascunhos iniciais do HTML5&lt;/a&gt;, mas foram removidos nas suas &lt;a href=&quot;http://www.w3.org/TR/2010/WD-html5-20101019/association-of-controls-and-forms.html#attr-fs-method&quot;&gt;versões subsequentes&lt;/a&gt;. Vai ver foi por isso que o Firefox acabou implementando-os e depois removendo-os. &lt;a href=&quot;http://html5.org/tools/web-apps-tracker?from=5565&amp;to=5566&quot;&gt;Fonte 1&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Aqui temos uma resposta do Ian Hickson, que fechou a &lt;em&gt;issue&lt;/em&gt; como &lt;em&gt;Won’t fix&lt;/em&gt;:&lt;/p&gt;
&lt;blockquote&gt;
    &lt;p&gt;
        PUT as a form method makes no sense, you wouldn't want to PUT a form
        payload. DELETE only makes sense if there is no payload, so it doesn't make
        much sense with forms either.
    &lt;/p&gt;
    &lt;footer&gt;
        — Ian Hickson
        (&lt;a href='https://www.w3.org/Bugs/Public/show_bug.cgi?id=10671'&gt;Fonte 2&lt;/a&gt;)
    &lt;/footer&gt;
&lt;/blockquote&gt;
&lt;p&gt;E vocês, o que acham?&lt;/p&gt;

    </content>
  </entry>
  
  <entry>
    <id>http://loopinfinito.com.br/2014/05/27/miniaturas-simplificadas-com-css3</id>
    <title>Miniaturas simplificadas com CSS3</title>
    <updated>2014-05-27T00:00:00-07:00</updated>
    <link href="http://loopinfinito.com.br/2014/05/27/miniaturas-simplificadas-com-css3/" />
    <author>
      <name>Almir Filho</name>
      <uri>http://twitter.com/almirfilho</uri>
    </author>
    <content type="html">
      
      
      &lt;p&gt;&lt;img itemprop=&quot;thumbnailUrl&quot; src=&quot;http://loopinfinito.com.br/images/posts/2014-05-27-miniaturas.jpg&quot; alt=&quot;Miniaturas simplificadas com CSS3&quot; title=&quot;Miniaturas simplificadas com CSS3&quot; width=&quot;700&quot; height=&quot;432&quot; /&gt;&lt;/p&gt;
      
      &lt;style type='text/css'&gt;
.galeria {
	display: block;
	box-sizing: border-box;
	width: 700px;
	position: relative;
	left: -50px;
	font-size: 0;
	text-align: center;
	line-height: 0;
}
#content .post-container article &gt; section img.galeria-img {
	position: static;
	display: inline-block;
	left: 0;
	width: 140px;
	height: 140px;
	border: 1px solid #ccc;
	margin: 12px;
	font-size: 15px;
	background: #ddd;
}
#content .post-container article &gt; section img.galeria-img.original {
	width: auto;
	height: auto;
}
.galeria-img.fill {
	object-fit: fill;
}
.galeria-img.none {
	object-fit: none;
}
.galeria-img.cover {
	object-fit: cover;
}
.galeria-img.contain {
	object-fit: contain;
}
.galeria-img.scale-down {
	object-fit: scale-down;
}
.galeria-figure {
	display: inline-block;
}
.galeria-figure figcaption {
	font-size: 13px;
	line-height: 150%;
}
.galeria-arrow {
	display: inline-block;
	width: 37px;
	height: 30px;
	background: url(/images/posts/2014-05-27-arrow.png);
	vertical-align: 75px;
	margin: 0 20px;
}
.galeria-arrow.small {
	margin: 0;
}
.galeria-arrow.tall {
	vertical-align: 120px;
}
&lt;/style&gt;
&lt;p&gt;Perambulando pelos padrões da W3C, encontrei uma coisa bem interessante na &lt;a href=&quot;http://www.w3.org/TR/css3-images/&quot;&gt;especificação de imagens CSS3&lt;/a&gt; — a mesma que define os gradientes. Trata-se do modo de definição de tamanhos para imagens com as propriedades CSS &lt;code&gt;object-fit&lt;/code&gt; e &lt;code&gt;object-position&lt;/code&gt;, o que achei bastante útil principalmente para quando precisamos construir miniaturas (&lt;em&gt;thumbnails&lt;/em&gt;) para visualizar imagens. Abaixo temos uma mini galeria com algumas imagens.&lt;/p&gt;
&lt;p class='obs'&gt;
	&lt;strong&gt;OBS.:&lt;/strong&gt; Para visualizar os resultados experimentados neste
	post, é preciso utilizar um navegador baseado na engine do Blink (Google
	Chrome ou Opera) — caso contrário, não fará o menos sentido ler este
	material sem ver os resultados.
&lt;/p&gt;&lt;div class='galeria'&gt;
	&lt;img alt='Imagem 1' class='galeria-img fill' src='http://loopinfinito.com.br/images/posts/2014-05-27-miniatura1.jpg' /&gt;
	&lt;img alt='Imagem 2' class='galeria-img none' src='http://loopinfinito.com.br/images/posts/2014-05-27-miniatura1.jpg' /&gt;
	&lt;img alt='Imagem 3' class='galeria-img cover' src='http://loopinfinito.com.br/images/posts/2014-05-27-miniatura1.jpg' /&gt;
	&lt;img alt='Imagem 4' class='galeria-img contain' src='http://loopinfinito.com.br/images/posts/2014-05-27-miniatura1.jpg' /&gt;
	&lt;img alt='Imagem 5' class='galeria-img fill' src='http://loopinfinito.com.br/images/posts/2014-05-27-miniatura2.jpg' /&gt;
	&lt;img alt='Imagem 6' class='galeria-img none' src='http://loopinfinito.com.br/images/posts/2014-05-27-miniatura2.jpg' /&gt;
	&lt;img alt='Imagem 7' class='galeria-img cover' src='http://loopinfinito.com.br/images/posts/2014-05-27-miniatura2.jpg' /&gt;
	&lt;img alt='Imagem 8' class='galeria-img contain' src='http://loopinfinito.com.br/images/posts/2014-05-27-miniatura2.jpg' /&gt;
&lt;/div&gt;
&lt;p&gt;As miniaturas acima foram compostas &lt;strong&gt;apenas&lt;/strong&gt; com o elemento &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt;, ou seja, não foi preciso fazer uso de um elemento pai para servir de &lt;em&gt;empacotador&lt;/em&gt; para a imagem — coisa que é muito comum na construção de miniaturas, costuma-se utilizar uma &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; com &lt;code&gt;overflow: hidden&lt;/code&gt; e fazer o redimensionamento da imagem para acompanhar o tamanho da &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='html'&gt;&lt;span class='c'&gt;&amp;lt;!-- Isso --&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;img&lt;/span&gt; &lt;span class='na'&gt;class=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;galeria-img&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;src=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;einstein.jpg&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;alt=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;Einstein&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;

&lt;span class='c'&gt;&amp;lt;!-- Não isso --&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;div&lt;/span&gt; &lt;span class='na'&gt;class=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;galeria-thumb&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;img&lt;/span&gt;  &lt;span class='na'&gt;class=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;galeria-img&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;src=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;einstein.jpg&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;alt=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;Einstein&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note que as quatro primeiras imagens são a mesma imagem, assim como as quatro últimas. A imagem do Einstein tem uma orientação de retrato (altura maior que largura), enquanto que a imagem do Chico Science tem uma orientação de paisagem (largura maior que altura).&lt;/p&gt;

&lt;h2 id=&quot;objectfit&quot;&gt;object-fit&lt;/h2&gt;

&lt;p&gt;Cada uma das quatro ocorrências dessas imagens tem um comportamento diferente. Esse comportamento é definido através da propriedade &lt;code&gt;object-fit&lt;/code&gt;, e com o uso dessa propriedade, fica visível que há uma separação entre o &lt;strong&gt;elemento invólucro&lt;/strong&gt; (pai) e o &lt;strong&gt;conteúdo&lt;/strong&gt; (&lt;em&gt;bitmap&lt;/em&gt;) da imagem — o que já dá para perceber se utilizarmos a propriedade &lt;code&gt;padding&lt;/code&gt; em uma imagem.&lt;/p&gt;

&lt;p&gt;Então, o elemento &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; não é apenas um elemento, afinal de contas; mas pelo menos dois — assim como a maioria dos elementos HTML, afinal, a &lt;a href=&quot;http://loopinfinito.com.br/2012/07/17/sou-dom-shadow-dom/&quot; title=&quot;Sou DOM, Shadow
DOM&quot;&gt;Shadow DOM&lt;/a&gt; está aí.&lt;/p&gt;

&lt;p&gt;A propriedade &lt;code&gt;object-fit&lt;/code&gt; define como o conteúdo da imagem é apresentado em relação ao seu elemento invólucro (elemento pai), e pode ter seu valor igual a &lt;code&gt;fill&lt;/code&gt;, &lt;code&gt;none&lt;/code&gt;, &lt;code&gt;cover&lt;/code&gt;, &lt;code&gt;contain&lt;/code&gt; ou &lt;code&gt;scale-down&lt;/code&gt;. Para notar as diferenças do uso dessa propriedade, é necessário que a imagem em questão tenha altura e largura definidas. No nosso exemplo acima temos ambas as dimensões com 140 &lt;em&gt;pixels&lt;/em&gt;:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='css'&gt;&lt;span class='nc'&gt;.galeria-img&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;width&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;140px&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;height&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;140px&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Agora, vamos ao que interessa.&lt;/p&gt;

&lt;h3 id=&quot;fill&quot;&gt;fill&lt;/h3&gt;

&lt;p&gt;Este é o valor padrão para &lt;code&gt;object-fit&lt;/code&gt;. Para uma imagem com com altura e largura definidas, sua forma será &lt;strong&gt;achatada&lt;/strong&gt; se a proporção resultante for diferente da original (comportamento padrão das imagens até então).&lt;/p&gt;
&lt;div class='galeria'&gt;
	&lt;figure class='galeria-figure'&gt;
		&lt;img alt='Imagem Original' class='galeria-img original' src='http://loopinfinito.com.br/images/posts/2014-05-27-miniatura1.jpg' /&gt;
		&lt;figcaption&gt;Imagem original&lt;/figcaption&gt;
	&lt;/figure&gt;
	&lt;div class='galeria-arrow'&gt; &lt;/div&gt;
	&lt;figure class='galeria-figure'&gt;
		&lt;img alt='Imagem com fill' class='galeria-img fill' src='http://loopinfinito.com.br/images/posts/2014-05-27-miniatura1.jpg' /&gt;
		&lt;figcaption&gt;140x140px com &lt;code&gt;fill&lt;/code&gt;&lt;/figcaption&gt;
	&lt;/figure&gt;
&lt;/div&gt;&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='css'&gt;&lt;span class='nc'&gt;.galeria-img&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;width&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;140px&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;height&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;140px&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='n'&gt;object&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='n'&gt;fit&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;fill&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;none&quot;&gt;none&lt;/h3&gt;

&lt;p&gt;Com &lt;code&gt;none&lt;/code&gt;, não é realizado nenhum processamento na imagem, mas ela será “&lt;em&gt;cropada&lt;/em&gt;” (&lt;em&gt;crop&lt;/em&gt;) pelas dimensões definidas, ou seja, será renderizada com seu &lt;em&gt;bitmap&lt;/em&gt; inalterado, porém &lt;strong&gt;cortado&lt;/strong&gt;. Com um exemplo fica mais fácil de entender:&lt;/p&gt;
&lt;div class='galeria'&gt;
	&lt;figure class='galeria-figure'&gt;
		&lt;img alt='Imagem Original' class='galeria-img original' src='http://loopinfinito.com.br/images/posts/2014-05-27-miniatura1.jpg' /&gt;
		&lt;figcaption&gt;Imagem original&lt;/figcaption&gt;
	&lt;/figure&gt;
	&lt;div class='galeria-arrow'&gt; &lt;/div&gt;
	&lt;figure class='galeria-figure'&gt;
		&lt;img alt='Imagem com none' class='galeria-img none' src='http://loopinfinito.com.br/images/posts/2014-05-27-miniatura1.jpg' /&gt;
		&lt;figcaption&gt;140x140px com &lt;code&gt;none&lt;/code&gt;&lt;/figcaption&gt;
	&lt;/figure&gt;
&lt;/div&gt;&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='css'&gt;&lt;span class='nc'&gt;.galeria-img&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;width&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;140px&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;height&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;140px&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='n'&gt;object&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='n'&gt;fit&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='k'&gt;none&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Agora, vejamos o que acontece quando uma das dimensões definidas excede sua correspondente original:&lt;/p&gt;
&lt;div class='galeria'&gt;
	&lt;figure class='galeria-figure'&gt;
		&lt;img alt='Imagem Original' class='galeria-img original' src='http://loopinfinito.com.br/images/posts/2014-05-27-miniatura1.jpg' /&gt;
		&lt;figcaption&gt;Imagem original&lt;/figcaption&gt;
	&lt;/figure&gt;
	&lt;div class='galeria-arrow'&gt; &lt;/div&gt;
	&lt;figure class='galeria-figure'&gt;
		&lt;img alt='Imagem com none' class='galeria-img none' src='http://loopinfinito.com.br/images/posts/2014-05-27-miniatura1.jpg' style='width: 220px;' /&gt;
		&lt;figcaption&gt;220x140px com &lt;code&gt;none&lt;/code&gt;&lt;/figcaption&gt;
	&lt;/figure&gt;
&lt;/div&gt;&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='css'&gt;&lt;span class='nc'&gt;.galeria-img&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;width&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;220px&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;height&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;140px&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='n'&gt;object&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='n'&gt;fit&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='k'&gt;none&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Como dito, nenhum processamento foi feito na imagem, e ela mantém seu tamanho original. Pode-se perceber também que, nesses dois exemplos, a imagem resultante foi posicionada de forma centralizada. Veremos isso mais adiante com a propriedade &lt;a href=&quot;#objectposition&quot;&gt;&lt;code&gt;object-position&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;cover&quot;&gt;cover&lt;/h3&gt;

&lt;p&gt;Igualmente a &lt;code&gt;none&lt;/code&gt;, mantém a proporção original da imagem, porém faz um redimensionamento na imagem para que esta possa &lt;strong&gt;preencher&lt;/strong&gt; toda a área definida pelas dimensões especificadas. A seguir temos o mesmo exemplo do caso anterior, a única coisa que muda é o valor de &lt;code&gt;object-fit&lt;/code&gt; para &lt;code&gt;cover&lt;/code&gt;.&lt;/p&gt;
&lt;div class='galeria'&gt;
	&lt;figure class='galeria-figure'&gt;
		&lt;img alt='Imagem Original' class='galeria-img original' src='http://loopinfinito.com.br/images/posts/2014-05-27-miniatura1.jpg' /&gt;
		&lt;figcaption&gt;Imagem original&lt;/figcaption&gt;
	&lt;/figure&gt;
	&lt;div class='galeria-arrow'&gt; &lt;/div&gt;
	&lt;figure class='galeria-figure'&gt;
		&lt;img alt='Imagem com cover' class='galeria-img cover' src='http://loopinfinito.com.br/images/posts/2014-05-27-miniatura1.jpg' style='width: 220px;' /&gt;
		&lt;figcaption&gt;220x140px com &lt;code&gt;cover&lt;/code&gt;&lt;/figcaption&gt;
	&lt;/figure&gt;
&lt;/div&gt;&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='css'&gt;&lt;span class='nc'&gt;.galeria-img&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;width&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;220px&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;height&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;140px&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='n'&gt;object&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='n'&gt;fit&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;cover&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;contain&quot;&gt;contain&lt;/h3&gt;

&lt;p&gt;Mantém a proporção original como em &lt;code&gt;cover&lt;/code&gt;, mas faz um redimensionamento na imagem de modo que esta não seja cortada e seja &lt;strong&gt;mostrada completamente&lt;/strong&gt; dentro da área definida pelas dimensões especificadas.&lt;/p&gt;
&lt;div class='galeria'&gt;
	&lt;figure class='galeria-figure'&gt;
		&lt;img alt='Imagem Original' class='galeria-img original' src='http://loopinfinito.com.br/images/posts/2014-05-27-miniatura1.jpg' /&gt;
		&lt;figcaption&gt;Imagem original&lt;/figcaption&gt;
	&lt;/figure&gt;
	&lt;div class='galeria-arrow'&gt; &lt;/div&gt;
	&lt;figure class='galeria-figure'&gt;
		&lt;img alt='Imagem com contain' class='galeria-img contain' src='http://loopinfinito.com.br/images/posts/2014-05-27-miniatura1.jpg' /&gt;
		&lt;figcaption&gt;140x140px com &lt;code&gt;contain&lt;/code&gt;&lt;/figcaption&gt;
	&lt;/figure&gt;
&lt;/div&gt;&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='css'&gt;&lt;span class='nc'&gt;.galeria-img&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;width&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;140px&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;height&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;140px&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='n'&gt;object&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='n'&gt;fit&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;contain&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;scaledown&quot;&gt;scale-down&lt;/h3&gt;

&lt;p&gt;Esse é um valor que pode causar um pouco de confusão. Ele fará com que a imagem se comporte de dois jeitos diferentes, dependendo do seu tamanho. &lt;code&gt;scale-down&lt;/code&gt; irá sempre se comportar igual a &lt;code&gt;none&lt;/code&gt; ou &lt;code&gt;contain&lt;/code&gt;. O comportamento resultante sempre será o que representar um &lt;strong&gt;menor tamanho&lt;/strong&gt; de imagem desenhada — e isso dependerá das dimensões originais da imagem e das dimensões definidas para o elemento &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt;. De novo, com um exemplo fica mais fácil:&lt;/p&gt;
&lt;div class='galeria'&gt;
	&lt;figure class='galeria-figure'&gt;
		&lt;img alt='Imagem Original' class='galeria-img original' src='http://loopinfinito.com.br/images/posts/2014-05-27-miniatura1.jpg' /&gt;
		&lt;figcaption&gt;Imagem original&lt;/figcaption&gt;
	&lt;/figure&gt;
	&lt;div class='galeria-arrow small tall'&gt; &lt;/div&gt;
	&lt;figure class='galeria-figure'&gt;
		&lt;img alt='Imagem com scale-down' class='galeria-img scale-down' src='http://loopinfinito.com.br/images/posts/2014-05-27-miniatura1.jpg' style='height:250px; width:120px;' /&gt;
		&lt;figcaption&gt;120x250px &lt;code&gt;scale-down&lt;/code&gt;&lt;/figcaption&gt;
	&lt;/figure&gt;
	&lt;div class='galeria-arrow small tall'&gt; &lt;/div&gt;
	&lt;figure class='galeria-figure'&gt;
		&lt;img alt='Imagem com scale-down' class='galeria-img scale-down' src='http://loopinfinito.com.br/images/posts/2014-05-27-miniatura1.jpg' style='height:250px; width:200px;' /&gt;
		&lt;figcaption&gt;200x250px com &lt;code&gt;scale-down&lt;/code&gt;&lt;/figcaption&gt;
	&lt;/figure&gt;
&lt;/div&gt;&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='css'&gt;&lt;span class='nc'&gt;.einstein-fit-1&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;width&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;120px&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;height&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;250px&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='n'&gt;object&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='n'&gt;fit&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;scale&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='n'&gt;down&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='nc'&gt;.einstein-fit-2&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;width&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;200px&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;height&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;250px&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='n'&gt;object&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='n'&gt;fit&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;scale&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='n'&gt;down&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Podemos perceber que nas duas imagens temos a mesma altura, e apenas mudamos a largura de um para o outro. No primeiro caso, &lt;code&gt;scale-down&lt;/code&gt; se comporta como &lt;code&gt;contain&lt;/code&gt;, pois &lt;code&gt;none&lt;/code&gt; resultaria numa imagem maior. Já no segundo caso, temos o oposto, &lt;code&gt;scale-down&lt;/code&gt; se comporta como &lt;code&gt;none&lt;/code&gt;, pois &lt;code&gt;contain&lt;/code&gt; resultaria numa imagem maior. Simples, não é?&lt;/p&gt;

&lt;h2 id=&quot;objectposition&quot;&gt;object-position&lt;/h2&gt;

&lt;p&gt;O propósito de &lt;code&gt;object-position&lt;/code&gt; é bem simples: posicionar o conteúdo da imagem dentro do emento &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt;. O seu valor é definido exatamente da mesma maneira que a propriedade &lt;code&gt;background-position&lt;/code&gt;. No exemplo a seguir temos imagens definidas com &lt;code&gt;object-fit: cover&lt;/code&gt; e modificamos seu alinhamento vertical.&lt;/p&gt;
&lt;div class='galeria'&gt;
	&lt;figure class='galeria-figure'&gt;
		&lt;img alt='Imagem com cover' class='galeria-img cover' src='http://loopinfinito.com.br/images/posts/2014-05-27-miniatura1.jpg' /&gt;
		&lt;figcaption&gt;140x140px com &lt;code&gt;cover&lt;/code&gt;&lt;/figcaption&gt;
	&lt;/figure&gt;
	&lt;div class='galeria-arrow small'&gt; &lt;/div&gt;
	&lt;figure class='galeria-figure'&gt;
		&lt;img alt='Imagem com cover' class='galeria-img cover' src='http://loopinfinito.com.br/images/posts/2014-05-27-miniatura1.jpg' style='object-position:50% 0%;' /&gt;
		&lt;figcaption&gt;140x140px com &lt;code&gt;cover&lt;/code&gt; no topo&lt;/figcaption&gt;
	&lt;/figure&gt;
	&lt;div class='galeria-arrow small'&gt; &lt;/div&gt;
	&lt;figure class='galeria-figure'&gt;
		&lt;img alt='Imagem com cover' class='galeria-img cover' src='http://loopinfinito.com.br/images/posts/2014-05-27-miniatura1.jpg' style='object-position:50% 100%;' /&gt;
		&lt;figcaption&gt;140x140px com &lt;code&gt;cover&lt;/code&gt; na base&lt;/figcaption&gt;
	&lt;/figure&gt;
&lt;/div&gt;&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='css'&gt;&lt;span class='nc'&gt;.einstein-fit-1&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='n'&gt;object&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='n'&gt;fit&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;cover&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='n'&gt;object&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='k'&gt;position&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;50&lt;/span&gt;&lt;span class='o'&gt;%&lt;/span&gt; &lt;span class='m'&gt;50&lt;/span&gt;&lt;span class='o'&gt;%&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='c'&gt;/* valor padrão */&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='nc'&gt;.einstein-fit-2&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='n'&gt;object&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='n'&gt;fit&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;cover&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='n'&gt;object&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='k'&gt;position&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;50&lt;/span&gt;&lt;span class='o'&gt;%&lt;/span&gt; &lt;span class='m'&gt;0&lt;/span&gt;&lt;span class='o'&gt;%&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='c'&gt;/* alinhada ao topo */&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='nc'&gt;.einstein-fit-3&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='n'&gt;object&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='n'&gt;fit&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;cover&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='n'&gt;object&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='k'&gt;position&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;50&lt;/span&gt;&lt;span class='o'&gt;%&lt;/span&gt; &lt;span class='m'&gt;100&lt;/span&gt;&lt;span class='o'&gt;%&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='c'&gt;/* alinhada à base */&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Agora, para ilustrar o alinhamento horizontal, no exemplo a seguir temos imagens definidas com &lt;code&gt;object-fit: contain&lt;/code&gt;.&lt;/p&gt;
&lt;div class='galeria'&gt;
	&lt;figure class='galeria-figure'&gt;
		&lt;img alt='Imagem com contain' class='galeria-img contain' src='http://loopinfinito.com.br/images/posts/2014-05-27-miniatura1.jpg' /&gt;
		&lt;figcaption&gt;140x140px com &lt;code&gt;contain&lt;/code&gt;&lt;/figcaption&gt;
	&lt;/figure&gt;
	&lt;div class='galeria-arrow small'&gt; &lt;/div&gt;
	&lt;figure class='galeria-figure'&gt;
		&lt;img alt='Imagem com contain' class='galeria-img contain' src='http://loopinfinito.com.br/images/posts/2014-05-27-miniatura1.jpg' style='object-position:0% 50%;' /&gt;
		&lt;figcaption&gt;140x140px com &lt;code&gt;contain&lt;/code&gt; no topo&lt;/figcaption&gt;
	&lt;/figure&gt;
	&lt;div class='galeria-arrow small'&gt; &lt;/div&gt;
	&lt;figure class='galeria-figure'&gt;
		&lt;img alt='Imagem com contain' class='galeria-img contain' src='http://loopinfinito.com.br/images/posts/2014-05-27-miniatura1.jpg' style='object-position:100% 50%;' /&gt;
		&lt;figcaption&gt;140x140px com &lt;code&gt;contain&lt;/code&gt; na base&lt;/figcaption&gt;
	&lt;/figure&gt;
&lt;/div&gt;&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='css'&gt;&lt;span class='nc'&gt;.einstein-fit-1&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='n'&gt;object&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='n'&gt;fit&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;contain&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='n'&gt;object&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='k'&gt;position&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;50&lt;/span&gt;&lt;span class='o'&gt;%&lt;/span&gt; &lt;span class='m'&gt;50&lt;/span&gt;&lt;span class='o'&gt;%&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='c'&gt;/* valor padrão */&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='nc'&gt;.einstein-fit-2&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='n'&gt;object&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='n'&gt;fit&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;contain&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='n'&gt;object&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='k'&gt;position&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;0&lt;/span&gt;&lt;span class='o'&gt;%&lt;/span&gt; &lt;span class='m'&gt;50&lt;/span&gt;&lt;span class='o'&gt;%&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='c'&gt;/* alinhada à esquerda */&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='nc'&gt;.einstein-fit-3&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='n'&gt;object&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='n'&gt;fit&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;contain&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='n'&gt;object&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='k'&gt;position&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;100&lt;/span&gt;&lt;span class='o'&gt;%&lt;/span&gt; &lt;span class='m'&gt;50&lt;/span&gt;&lt;span class='o'&gt;%&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='c'&gt;/* alinhada à direita */&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Claro que também é possível utilizar outras unidades como &lt;code&gt;px&lt;/code&gt;, &lt;code&gt;em&lt;/code&gt;, etc. e valores negativos também.&lt;/p&gt;

&lt;h2 id=&quot;ah_e_mais_uma_coisinha&quot;&gt;Ah, e mais uma coisinha…&lt;/h2&gt;

&lt;p&gt;As propriedades &lt;code&gt;object-fit&lt;/code&gt; e &lt;code&gt;object-position&lt;/code&gt; podem ser utilizadas também no elemento &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt;, nos possibilitando realizar exatamente as mesmas configurações de estilos tanto para imagens quanto para vídeos.&lt;/p&gt;
&lt;table class='support'&gt;
    &lt;thead&gt;
        &lt;tr&gt;
            &lt;th class='subject'&gt;&lt;h2&gt;Suporte&lt;/h2&gt;&lt;/th&gt;
            &lt;th class='browser chrome'&gt;&lt;div class='i' /&gt;&lt;/th&gt;
            &lt;th class='browser safari'&gt;&lt;div class='i' /&gt;&lt;/th&gt;
            &lt;th class='browser firefox'&gt;&lt;div class='i' /&gt;&lt;/th&gt;
            &lt;th class='browser ie'&gt;&lt;div class='i' /&gt;&lt;/th&gt;
            &lt;th class='browser opera'&gt;&lt;div class='i' /&gt;&lt;/th&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;th /&gt;
            &lt;th class='base' colspan='5' /&gt;
        &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class='property'&gt;&lt;code&gt;object-fit&lt;/code&gt;&lt;/td&gt;
            &lt;td&gt;31&lt;/td&gt;
            &lt;td&gt;--&lt;/td&gt;
            &lt;td&gt;--&lt;/td&gt;
            &lt;td&gt;--&lt;/td&gt;
            &lt;td&gt;19&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class='property'&gt;&lt;code&gt;object-position&lt;/code&gt;&lt;/td&gt;
            &lt;td&gt;31&lt;/td&gt;
            &lt;td&gt;--&lt;/td&gt;
            &lt;td&gt;--&lt;/td&gt;
            &lt;td&gt;--&lt;/td&gt;
            &lt;td&gt;19&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Informações segundo o &lt;a href=&quot;http://caniuse.com/#search=object-fit&quot; title=&quot;object-fit no caniuse.com&quot;&gt;caniuse&lt;/a&gt;. Apenas o Google Chrome e o Opera dão suporte atualmente (logicamente, agora que o Opera também usa o Blink).&lt;/p&gt;

    </content>
  </entry>
  
  <entry>
    <id>http://loopinfinito.com.br/2014/04/01/2-anos-um-ola-e-um-adeus</id>
    <title>2 anos, um olá e um adeus</title>
    <updated>2014-04-01T00:00:00-07:00</updated>
    <link href="http://loopinfinito.com.br/2014/04/01/2-anos-um-ola-e-um-adeus/" />
    <author>
      <name>Almir Filho</name>
      <uri>http://twitter.com/almirfilho</uri>
    </author>
    <content type="html">
      
      
      &lt;p&gt;&lt;img itemprop=&quot;thumbnailUrl&quot; src=&quot;http://loopinfinito.com.br/images/posts/2014-04-01-2-anos.jpg&quot; alt=&quot;2 anos, um olá e um adeus&quot; title=&quot;2 anos, um olá e um adeus&quot; width=&quot;700&quot; height=&quot;432&quot; /&gt;&lt;/p&gt;
      
      
&lt;p&gt;Hoje, 1º de abril, estamos completando 2 anos de existência (&lt;a href=&quot;http://loopinfinito.com.br/2012/04/01/hello-web/&quot; title=&quot;Hello Web&quot;&gt;não é mentira&lt;/a&gt;), e como no &lt;a href=&quot;http://loopinfinito.com.br/2013/04/05/1-ano-de-loop/&quot; title=&quot;1 ano de
loop infinito&quot;&gt;ano passado&lt;/a&gt;, estou publicando mais um &lt;em&gt;post&lt;/em&gt; de retrospectiva sobre o Loop Infinito, além de algumas novidades.&lt;/p&gt;

&lt;h2 id=&quot;2_anos&quot;&gt;2 anos&lt;/h2&gt;

&lt;p&gt;Há exatos 2 anos, &lt;a href=&quot;https://twitter.com/caio_gondim&quot; title=&quot;Caio Gondim&quot;&gt;Caio&lt;/a&gt; e &lt;a href=&quot;https://twitter.com/almirfilho&quot; title=&quot;Almir Filho&quot;&gt;eu&lt;/a&gt; começamos esse projeto maravilhoso para nós, que se trata deste humilde blog sobre &lt;em&gt;front-end&lt;/em&gt;, produtividade e &lt;em&gt;lifestyle&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;De lá pra cá muita coisa aconteceu. Muita coisa mudou em nossas vidas. Decisões foram feitas, obstáculos foram superados, soluções foram descobertas, amizades foram firmadas, algumas decepções foram amargas, algumas conquistas não importaram, e no fim, muito se aprendeu — e esse sim é o objetivo principal para nós. Aprender. Tanto nós quanto vocês. Vocês são todos nossos parceiros nessa busca — a busca pelo conhecimento e pelo constante aprimoramento.&lt;/p&gt;

&lt;p&gt;Este ano não vou mostrar aquele monte de gráficos como da vez passada — apesar de gostar bastante disso =P. Mas selecionei alguns números importantes e plotei-os em comparação com o ano anterior. Para saber os números, &lt;strong&gt;passe o &lt;em&gt;mouse&lt;/em&gt; em cima dos gráficos&lt;/strong&gt;.&lt;/p&gt;

&lt;h3 id=&quot;quantidade_de_posts&quot;&gt;Quantidade de posts&lt;/h3&gt;
&lt;div class='img chart' id='chart-posts-por-ano'&gt; &lt;/div&gt;
&lt;p&gt;Esse é o número mais óbvio, pois tá na cara que nossa frequência de postagens deixou muito a desejar nesse ano — e nós reconhecemos isso. Eu poderia citar N razões plausíveis para isso agora, mas tenho certeza de que no fim tudo não passará de desculpas para nossos leitores, e eu não os culpo por pensar isso.&lt;/p&gt;

&lt;h3 id=&quot;ranking_de_localidades&quot;&gt;Ranking de localidades&lt;/h3&gt;
&lt;div class='img chart' id='chart-cidades'&gt; &lt;/div&gt;
&lt;p&gt;As cidades que mais nos visitam (não mudou muita coisa em relação ao ano anterior):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;São Paulo (22.16%)&lt;/li&gt;

&lt;li&gt;Rio de Janeiro (9.11%)&lt;/li&gt;

&lt;li&gt;Belo Horizonte (5.76%)&lt;/li&gt;

&lt;li&gt;Porto Alegre (4.67%)&lt;/li&gt;

&lt;li&gt;Curitiba (3.51%)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;ranking_de_navegadores&quot;&gt;Ranking de navegadores&lt;/h3&gt;
&lt;div class='img chart' id='chart-navegadores'&gt; &lt;/div&gt;
&lt;p&gt;Essa ainda é a minha parte preferida. Abaixo temos uma comparação com o ano anterior.&lt;/p&gt;
&lt;div class='img chart' id='chart-navegadores-comparacao'&gt; &lt;/div&gt;
&lt;p&gt;O Chrome ganhou ainda mais espaço (+1.2%), mas o Safari foi o que mais cresceu, obtendo um ganho (+3.1%) maior que o Chrome. O restante dos navegadores perdeu espaço.&lt;/p&gt;

&lt;h2 id=&quot;conferncias&quot;&gt;Conferências&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2014-04-01-eventos-2013.jpg&quot; alt=&quot;Conferências&quot; title=&quot;Conferências em 2013&quot; /&gt;&lt;/p&gt;

&lt;p&gt;2013 foi de longe o ano em que mais participamos de conferências de &lt;em&gt;web&lt;/em&gt;, especialmente de &lt;em&gt;front-end&lt;/em&gt;. &lt;a href=&quot;http://loopinfinito.com.br/palestras/&quot;&gt;Palestramos&lt;/a&gt; em alguns eventos regionais e participamos das grandes conferências como a &lt;a href=&quot;http://2013.jsconfbr.org/&quot; title=&quot;JSConf BR 2013&quot;&gt;JSConf BR&lt;/a&gt; e &lt;a href=&quot;http://braziljs.com.br/2013/&quot; title=&quot;BrazilJS Conf 2013&quot;&gt;BrazilJS Conf&lt;/a&gt;, ambas de alto nível e imperdíveis (falando nisso, já garantiu sua entrada para a &lt;a href=&quot;http://braziljs.com.br/2014/&quot; title=&quot;BrazilJS Conf 2014&quot;&gt;BrazilJS Conf&lt;/a&gt; deste ano?).&lt;/p&gt;

&lt;p&gt;É sempre muito bom reencontrar os amigos que moram espalhados pelo país, além de trocar ideias com os participantes e palestrantes dos eventos — principalmente quando tem &lt;em&gt;aquele chopp&lt;/em&gt; depois.&lt;/p&gt;

&lt;h2 id=&quot;um_ol&quot;&gt;Um olá&lt;/h2&gt;

&lt;p&gt;Bem, como mostrado, nós faltamos bastante com nosso compromisso de manter o &lt;em&gt;blog&lt;/em&gt; com novidades na maior parte do tempo, mas acreditamos que 2014 tem tudo para ser melhor que 2013. Vamos nos focar mais nisso e manteremos o &lt;a href=&quot;http://setup.loopinfinito.com.br/&quot; title=&quot;Setup&quot;&gt;Setup&lt;/a&gt; trazendo sempre as pessoas mais f***s que conhecemos da &lt;em&gt;web&lt;/em&gt; brasileira. Algumas pessoas reclamam que a periodicidade do Setup é muito alta (1 &lt;em&gt;setup&lt;/em&gt; por mês) — e realmente é, mas tem uma boa razão para isso e acredito que vocês sabem qual é: qualidade e compromisso. Acreditem, não é fácil ter que escolher apenas &lt;strong&gt;uma pessoa&lt;/strong&gt; por mês em meio a tanta gente boa. Também vamos voltar a atualizar o &lt;a href=&quot;http://wiredin.loopinfinito.com.br/&quot;&gt;wiredIn()&lt;/a&gt; (coisa que queremos há muito tempo), então podem esperar por &lt;em&gt;playlists&lt;/em&gt; ainda melhores e um &lt;em&gt;redesign&lt;/em&gt; do projeto.&lt;/p&gt;

&lt;h2 id=&quot;um_adeus&quot;&gt;Um adeus?&lt;/h2&gt;

&lt;p&gt;Como alguns já devem estar sabendo, Caio está indo morar em Amsterdã, e isso pode influenciar bastante em como as coisas vão se desenrolar daqui pra frente. Chegamos até a conversar sobre encerrar as atividades no Loop Infinito, e cada um continuar a fazer suas postagens em seus respectivos &lt;em&gt;blogs&lt;/em&gt;. Porém, a ideia me pareceu um absurdo, e confesso que não me dei bem com essa possibilidade. Ainda não consigo me imaginar fazendo isso, pelo menos não por um bom tempo pela frente.&lt;/p&gt;

&lt;p&gt;O que foi decidido enfim foi o seguinte: &lt;strong&gt;vamos continuar na ativa por aqui&lt;/strong&gt;, e depois de um certo tempo tentar perceber se as coisas ainda estão fluindo legal. Então, o “adeus” na verdade é do Caio para sua morada aqui no Brasil, e não para o Loop.&lt;/p&gt;

&lt;h2 id=&quot;livro_coletnea_frontend&quot;&gt;Livro Coletânea Front-end&lt;/h2&gt;

&lt;p&gt;Nos últimos meses estávamos trabalhando em conjunto com mais 9 autores na elaboração desse, que se tornou no nosso primeiro material publicado em um livro. O convite veio do Sérgio Lopes (&lt;a href=&quot;https://twitter.com/sergio_caelum&quot;&gt;@sergio_caelum&lt;/a&gt;), que teve essa maravilhosa iniciativa. Para nós é uma grande honra poder compor algo juntamente com &lt;a href=&quot;https://twitter.com/bernarddeluna&quot;&gt;Bernard de Luna&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/deividmarques&quot;&gt;Deivid Marques&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/diegoeis&quot;&gt;Diego Eis&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/shiota&quot;&gt;Eduardo Shiota&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/Keppelen&quot;&gt;Giovanni Keppelen&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/srsaude&quot;&gt;Luiz Corte&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/jaydson&quot;&gt;Jaydson Gomes&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/reinaldoferraz&quot;&gt;Reinaldo Ferraz&lt;/a&gt;, e o próprio Sérgio, totalizando 11 autores, cada um com um capítulo independente.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2014-04-01-coletanea-front-end.jpg&quot; alt=&quot;Coletânea Front-end&quot; title=&quot;Coletânea Front-end&quot; /&gt;&lt;/p&gt;

&lt;p&gt;O livro &lt;a href=&quot;https://casadocodigo.refersion.com/l/32f.5685&quot;&gt;Coletânea Front-end: Uma antologia da comunidade front-end brasileira&lt;/a&gt; está sendo distribuído pela Casa do Código e &lt;strong&gt;está sendo publicado hoje&lt;/strong&gt; (também não é mentira de 1º de abril). Por enquanto só está disponível na versão eletrônica, mas a versão impressa também estará disponível em breve. Achei a capa animal!&lt;/p&gt;

&lt;p&gt;2014 promete, galera. Contamos com vocês para continuar movimentando a nossa comunidade. Valeu!&lt;/p&gt;
&lt;style type='text/css'&gt;
  .so { height: 230px; }
  .pull-left { float: left; }
  .pull-right { float: right; }
&lt;/style&gt;&lt;script src='http://google.com/jsapi' type='text/javascript'&gt; &lt;/script&gt;&lt;script type='text/javascript'&gt;

var color_verde = '#95E879',
  color_cinza = '#CCCCCC',
  color_cinza_claro = '#dddddd',
  color_cinza_escuro = '#999999',
  color_blue = '#99CCFF',
  color_orange = '#FFCC99',
  color_purple = '#DFBFFF',
  color_red = '#FFBFBF';

google.load('visualization', '1.0', {'packages':['corechart', 'geochart']});

google.setOnLoadCallback( function(){
  postsPorAno();
  cidades();
  navegadores();
  navegadoresComparacao();
});

var postsPorAno = function(){
  var data = new google.visualization.DataTable();
  data.addColumn( 'string', 'Posts por ano' );
  data.addColumn( 'number', 'Ano 1' );
  data.addColumn( 'number', 'Ano 2' );
  data.addRows([
    [ 'Almir Filho', 20, 11 ],
    [ 'Caio Gondim', 18, 14 ],
    [ 'Total de posts', 38, 25 ]
  ]);

  var chart = new google.visualization.BarChart( $('#chart-posts-por-ano')[0] );
  chart.draw( data, {
    width: 700,
    height: 250,
    chartArea: {
      width: 600,
      height: 300,
      left: 50,
      top: 10
    },
    colors: [color_blue, color_verde],
    legend: {
      textStyle: {
        color: color_cinza_escuro,
        fontSize: 11
      },
      position: 'in',
      alignment: 'end'
    },
    vAxis: {
      textPosition: 'in',
      textStyle: {
        color: color_cinza_escuro,
        fontSize: 14
      }
    },
    hAxis: {
      baselineColor: color_cinza,
      minValue: 0,
      maxValue: 38,
      gridlines: {
        color: color_cinza_claro,
        count: 5
      },
      textStyle: {
        color: color_cinza_escuro,
        fontSize: 12
      }
    }
  });
}

var cidades = function(){
  var data = new google.visualization.DataTable();
  data.addColumn( 'string', 'Cidade' );
  data.addColumn( 'number', 'Visitas (%)' );
  data.addRows([
    [ 'São Paulo',      0.2216 ],
    [ 'Rio de Janeiro', 0.0911 ],
    [ 'Belo Horizonte', 0.0576 ],
    [ 'Porto Alegre',   0.0467 ],
    [ 'Curitiba',       0.0351 ],
    [ 'Brasília',       0.0307 ],
    [ 'Recife',         0.0275 ],
    [ 'Fortaleza',      0.0233 ],
    [ 'Salvador',       0.0230 ],
    [ 'Campinas',       0.0212 ]
  ]);

  var chart = new google.visualization.GeoChart( $('#chart-cidades')[0] );
  chart.draw( data, {
    width: 700,
    height: 432,
    region: 'BR',
    displayMode: 'markers',
    colorAxis: {
      colors: [ color_blue, color_verde ]
    },
    legend: {
      numberFormat: '#%'
    }
  });
}

var navegadores = function(){
  var data = new google.visualization.DataTable();
  data.addColumn( 'string', 'Navegador' );
  data.addColumn( 'number', 'Visitas' );
  data.addRows([
    [ 'Chrome',  72.11 ],
    [ 'Firefox', 14.17 ],
    [ 'Safari',   7.85 ],
    [ 'IE',       2.27 ],
    [ 'Opera',    0.91 ],
    [ 'Outros',   2.69 ]
  ]);

  var chart = new google.visualization.PieChart( $('#chart-navegadores')[0] );
  chart.draw( data, {
    width: 700,
    height: 300,
    chartArea: {
      width: 600,
      left: 50,
      height: 280,
      top: 10
    },
    colors: [color_blue, color_orange, color_verde, color_purple, color_red, color_cinza_claro],
    legend: {
      position: 'right',
      alignment: 'center',
      textStyle: {
        color: color_cinza_escuro,
        fontSize: 16
      }
    }
  });
}

var navegadoresComparacao = function(){
  var data = new google.visualization.DataTable();
  data.addColumn( 'string', 'Navegadores por ano' );
  data.addColumn( 'number', 'Ano 1 (%)' );
  data.addColumn( 'number', 'Ano 2 (%)' );
  data.addRows([
    [ 'Chrome',  70.91, 72.11 ],
    [ 'Firefox', 17.35, 14.17 ],
    [ 'Safari',   4.77,  7.85 ],
    [ 'IE',       2.82,  2.27 ],
    [ 'Opera',    1.31,  0.91 ],
    [ 'Outros',   2.84,  2.69 ]
  ]);

  var chart = new google.visualization.BarChart( $('#chart-navegadores-comparacao')[0] );
  chart.draw( data, {
    width: 700,
    height: 432,
    chartArea: {
      width: 600,
      height: 400,
      left: 50,
      top: 10
    },
    colors: [color_blue, color_verde],
    legend: {
      textStyle: {
        color: color_cinza_escuro,
        fontSize: 11
      },
      position: 'in',
      alignment: 'end',
      numberFormat: '#%'
    },
    vAxis: {
      textPosition: 'in',
      textStyle: {
        color: color_cinza_escuro,
        fontSize: 14
      }
    },
    hAxis: {
      baselineColor: color_cinza,
      minValue: 0,
      maxValue: 100,
      gridlines: {
        color: color_cinza_claro,
        count: 5
      },
      textStyle: {
        color: color_cinza_escuro,
        fontSize: 12
      }
    }
  });
}

&lt;/script&gt;
    </content>
  </entry>
  
  <entry>
    <id>http://loopinfinito.com.br/2014/03/18/segredos-do-chrome-dev-tools</id>
    <title>Segredos do Chrome Developer Tools</title>
    <updated>2014-03-18T00:00:00-07:00</updated>
    <link href="http://loopinfinito.com.br/2014/03/18/segredos-do-chrome-dev-tools/" />
    <author>
      <name>Caio Gondim</name>
      <uri>http://twitter.com/caio_gondim</uri>
    </author>
    <content type="html">
      
      
      &lt;p&gt;&lt;img itemprop=&quot;thumbnailUrl&quot; src=&quot;http://loopinfinito.com.br/images/posts/2014-02-26-segredos-do-chrome-dev-tools.png&quot; alt=&quot;Segredos do Chrome Developer Tools&quot; title=&quot;Segredos do Chrome Developer Tools&quot; width=&quot;700&quot; height=&quot;432&quot; /&gt;&lt;/p&gt;
      
      
&lt;p&gt;Inspecionar elemento, &lt;em&gt;breakpoints&lt;/em&gt; em JavaScript e &lt;code&gt;console&lt;/code&gt; API já virou muito &lt;em&gt;mainstream&lt;/em&gt;. Vamos conhecer neste &lt;em&gt;post&lt;/em&gt; algumas &lt;em&gt;features&lt;/em&gt; mais &lt;em&gt;hipsters&lt;/em&gt; — porém úteis — do Chrome Developer Tools que vão melhorar seu dia-a-dia.&lt;/p&gt;

&lt;h2 id=&quot;compartilhar_e_analisar_uma_timeline_gravada_por_outro&quot;&gt;Compartilhar e analisar uma Timeline gravada por outro&lt;/h2&gt;

&lt;p&gt;Você está com aquele &lt;a href=&quot;http://www.youtube.com/watch?v=MLI2QlgjGmA&amp;feature=youtu.be&amp;t=4m0s&quot;&gt;bug Cássia Eller&lt;/a&gt; na sua aplicação, &lt;em&gt;deadline&lt;/em&gt; aproximando e você tem certeza que se fosse possível enviar os dados da sua &lt;em&gt;timeline&lt;/em&gt; para aquele seu amigo que manja de todos os paranauês do front-end, ele iria te ajudar.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Seus problemas se acabaram-se&lt;/strong&gt;. Agora você pode compartilhar sua &lt;em&gt;timeline&lt;/em&gt; e analisar uma gravação alheia. Na aba &lt;strong&gt;Timeline&lt;/strong&gt; clique com o botão secundário do &lt;em&gt;mouse&lt;/em&gt; em qualquer lugar e aparecerá uma opção para salvar e uma outra para carregar dados de uma &lt;em&gt;Timeline&lt;/em&gt; gravada.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt='Atalho para preservar o log entre navegação' src='http://loopinfinito.com.br/images/posts/2014-02-26-compartilhar-e-analisar-uma-timeline-gravado-por-outro.png' width='700' /&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;emulando_dispositivos&quot;&gt;Emulando dispositivos&lt;/h2&gt;

&lt;p&gt;Permite emular o tamanho da tela, &lt;em&gt;pixel ratio&lt;/em&gt; e &lt;em&gt;user agent string&lt;/em&gt; dos dispositivos móveis mais populares. Para acessar essa &lt;em&gt;feature&lt;/em&gt;, chame o &lt;strong&gt;Console drawer&lt;/strong&gt; como indicado na figura abaixo.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt='Console drawer' src='http://loopinfinito.com.br/images/posts/2014-02-26-console-drawer.png' width='700' /&gt;
&lt;/figure&gt;
&lt;p&gt;Uma vez no &lt;em&gt;drawer&lt;/em&gt;, vá na aba &lt;strong&gt;Emulation&lt;/strong&gt; e escolha o aparelho que deseja emular. Caso o aparelho não esteja na lista, é possível inserir todos os dados de forma manual.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt='Emulando dispositivos' src='http://loopinfinito.com.br/images/posts/2014-02-26-emulando-dispositivos.png' width='700' /&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;emulando_acelermetro&quot;&gt;Emulando acelerômetro&lt;/h2&gt;

&lt;p&gt;Além de emular dispositivos móveis, podemos emular alguns de seus sensores. Para emular o acelerômetro, por exemplo, vá ao &lt;em&gt;drawer&lt;/em&gt; (o mesmo do item anterior), depois na aba &lt;em&gt;Emulation&lt;/em&gt; e clique no &lt;em&gt;checkbox Accelerometer&lt;/em&gt;. Você pode mexer a representação 3D do dispositivo para emular uma determinada posição ou pôr valores diretamente em cada eixo.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt='Emulando acelerômetro' src='http://loopinfinito.com.br/images/posts/2014-02-26-emulando-acelerometro.gif' width='700' /&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;contador_de_fps&quot;&gt;Contador de FPS&lt;/h2&gt;

&lt;p&gt;Útil para visualizar, em tempo real, o &lt;em&gt;frame rate&lt;/em&gt; de sua aplicação. Para ativá-lo, vá no &lt;em&gt;drawer&lt;/em&gt;, depois na aba &lt;strong&gt;Rendering&lt;/strong&gt; e clique no &lt;em&gt;checkbox&lt;/em&gt;  &lt;strong&gt;Show FPS meter&lt;/strong&gt;.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt='Como habilitar o contador de FPS' src='http://loopinfinito.com.br/images/posts/2014-02-26-como-habilitar-o-contador-de-fps.png' width='700' /&gt;
&lt;/figure&gt;
&lt;p&gt;Quando ativo, irá aparecer uma caixa preta no topo à direita com detalhes sobre a quantidade de &lt;em&gt;frames&lt;/em&gt; que estão sendo renderizados por segundo.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt='Contador de FPS' src='http://loopinfinito.com.br/images/posts/2014-02-26-show-fps-meter.png' width='700' /&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;debugar_requisies_ajax_de_forma_mais_fcil&quot;&gt;Debugar requisições Ajax de forma mais fácil&lt;/h2&gt;

&lt;p&gt;Na aba &lt;em&gt;&lt;strong&gt;Sources&lt;/strong&gt;&lt;/em&gt;, ao lado direito, é possível adicionar &lt;em&gt;breakpoints&lt;/em&gt; dinâmicos para que o código pare a execução toda vez que uma chamada XHR possua uma dada &lt;em&gt;string&lt;/em&gt; em sua URL.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt='Debugar requisições Ajax de forma mais fácil' src='http://loopinfinito.com.br/images/posts/2014-02-26-xhr-breakpoint.png' width='700' /&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;procure_por_uma_string_entre_todos_os_arquivos&quot;&gt;Procure por uma string entre todos os arquivos&lt;/h2&gt;

&lt;p&gt;Um dos atalhos que mais uso. Aperte &lt;code&gt;Cmd&lt;/code&gt; + &lt;code&gt;Opt&lt;/code&gt; + &lt;code&gt;F&lt;/code&gt; (&lt;code&gt;Ctrl&lt;/code&gt; + &lt;code&gt;Shift&lt;/code&gt; + &lt;code&gt;F&lt;/code&gt; no Windows e Linux) para procurar qualquer palavra ou expressão regular entre &lt;strong&gt;todos&lt;/strong&gt; os arquivos carregados (inclusive os carregados em tempo de execução).&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt='Procure por uma string entre todos os arquivos' src='http://loopinfinito.com.br/images/posts/2014-02-26-procure-por-uma-string-entre-todos-os-arquivos.png' width='700' /&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;replay_de_chamadas_ajax&quot;&gt;Replay de chamadas Ajax&lt;/h2&gt;

&lt;p&gt;Já pensou ter que refazer sempre aquele fluxo enorme na sua aplicação só para disparar novamente aquela requisição Ajax (XHR)? Com esse atalho você pode dar um &lt;em&gt;replay&lt;/em&gt; em qualquer chamada Ajax.&lt;/p&gt;

&lt;p&gt;Na aba &lt;strong&gt;Network&lt;/strong&gt;, clique com o botão secundário em cima de qualquer requisição XHR e escolha a opção &lt;strong&gt;Replay XHR&lt;/strong&gt;.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt='Replay de chamadas Ajax' src='http://loopinfinito.com.br/images/posts/2014-02-26-replay-de-chamadas-ajax.png' width='700' /&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;copiando_requisies_como_comando_curl&quot;&gt;Copiando requisições como comando cURL&lt;/h2&gt;

&lt;p&gt;Praticamente uma derivação do &lt;em&gt;replay&lt;/em&gt; de chamadas Ajax. Com a diferença que aqui é gerado um comando cURL da requisição feita, com todos os parâmetros e cabeçalhos. Cole no seu terminal e aperte &lt;code&gt;enter&lt;/code&gt; para disparar uma requisição idêntica à que foi disparada pelo seu navegador.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt='Copiando requisições como comando cURL' src='http://loopinfinito.com.br/images/posts/2014-02-26-copiando-requisicoes-como-comando-curl.png' width='700' /&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;troque_rapidamente_entre_abas&quot;&gt;Troque rapidamente entre abas&lt;/h2&gt;

&lt;p&gt;Para navegar de forma rápida entre as abas do Dev Tools, utilize &lt;code&gt;Cmd&lt;/code&gt; + &lt;code&gt;[&lt;/code&gt; e &lt;code&gt;Cmd&lt;/code&gt; + &lt;code&gt;]&lt;/code&gt; (ou &lt;code&gt;Ctrl&lt;/code&gt; + &lt;code&gt;[&lt;/code&gt; e &lt;code&gt;Ctrl&lt;/code&gt; + &lt;code&gt;]&lt;/code&gt; no Windows e Linux).&lt;/p&gt;

&lt;h2 id=&quot;preservar_o_log_do_console_durante_navegao&quot;&gt;Preservar o log do console durante navegação&lt;/h2&gt;

&lt;p&gt;Sabe quando você quer debugar algo que acontece um pouco antes de um &lt;em&gt;redirect&lt;/em&gt; mas o &lt;em&gt;redirect&lt;/em&gt; sempre apaga o &lt;em&gt;log&lt;/em&gt; do &lt;em&gt;console&lt;/em&gt;? Seus problemas acabaram. Clique com o botão direito no &lt;em&gt;console&lt;/em&gt; e escolha a opção &lt;em&gt;&lt;strong&gt;Preserve log upon navigation&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt='Atalho para preservar o log entre navegação' src='http://loopinfinito.com.br/images/posts/2014-02-26-preserve-log-upon-navigation.png' width='700' /&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;benchmark_usando_consoletime&quot;&gt;Benchmark usando console.time&lt;/h2&gt;

&lt;p&gt;Caso queira medir quanto tempo uma determinada operação leva para ser executada, basta usar &lt;code&gt;console.time()&lt;/code&gt; e, quando a operação acabar usar o método &lt;code&gt;console.timeEnd()&lt;/code&gt; passando a mesma &lt;em&gt;string&lt;/em&gt;, como no exemplo abaixo.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt='Atalho para preservar o log entre navegação' src='http://loopinfinito.com.br/images/posts/2014-02-26-console-time.png' width='700' /&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;limpando_o_histrico_do_console&quot;&gt;Limpando o histórico do console&lt;/h2&gt;

&lt;p&gt;Bastante útil quando se começa a usar mais a aba console. &lt;code&gt;Cmd&lt;/code&gt; + &lt;code&gt;K&lt;/code&gt; no OS X e &lt;code&gt;Ctrl&lt;/code&gt; + &lt;code&gt;L&lt;/code&gt; no Windows e Linux para limpar o console. Também funciona com o método &lt;code&gt;console.clear()&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;mais_um_segredo&quot;&gt;Mais um segredo&lt;/h2&gt;

&lt;p&gt;A capa do &lt;em&gt;post&lt;/em&gt; também possui um pequeno segredo. Existe um rosto escondido entre os grãos de café. Consegue achar, olhos de águia?&lt;/p&gt;

    </content>
  </entry>
  
  <entry>
    <id>http://loopinfinito.com.br/2014/02/11/vibration-api</id>
    <title>Vibration API</title>
    <updated>2014-02-11T00:00:00-08:00</updated>
    <link href="http://loopinfinito.com.br/2014/02/11/vibration-api/" />
    <author>
      <name>Almir Filho</name>
      <uri>http://twitter.com/almirfilho</uri>
    </author>
    <content type="html">
      
      
      &lt;p&gt;&lt;img itemprop=&quot;thumbnailUrl&quot; src=&quot;http://loopinfinito.com.br/images/posts/2014-02-11-vibration-api.jpg&quot; alt=&quot;Vibration API&quot; title=&quot;Vibration API&quot; width=&quot;700&quot; height=&quot;432&quot; /&gt;&lt;/p&gt;
      
      
&lt;p&gt;Embora &lt;strong&gt;ainda&lt;/strong&gt; não seja possível provocar terremotos de escala geográfica, já podemos fazer dispositivos vibrar com &lt;abbr title='HyperText Markup
Language'&gt;HTML5&lt;/abbr&gt;. Entenda por dispositivo qualquer meio de acesso que possua um &lt;em&gt;hardware&lt;/em&gt; específico que possibilite isso — como os dispositivos móveis, pois não faria o mínimo sentido seu computador vibrar (ou não?).&lt;/p&gt;

&lt;p&gt;Muitas dessas novas APIs de acesso a dispositivos são focadas em utilidades &lt;em&gt;mobile&lt;/em&gt; (assim como a &lt;a href=&quot;http://loopinfinito.com.br/2013/03/21/battery-api/&quot; title=&quot;Battery API&quot;&gt;Battery API&lt;/a&gt;), e eu diria que a Mozilla é a entidade que mais investe nessas especificações, pelo simples fato de que ela mantém o Firefox OS, cuja proposta é funcionar totalmente em cima dos padrões abertos da &lt;em&gt;web&lt;/em&gt;.&lt;/p&gt;

&lt;h2 id=&quot;curiosidade&quot;&gt;Curiosidade&lt;/h2&gt;

&lt;p&gt;Originalmente, o nome dessa &lt;abbr title='Application Programming
Interface'&gt;API&lt;/abbr&gt; seria &lt;strong&gt;Vibrator&lt;/strong&gt; (vibrador), mas, por questões óbvias, preferiram mudar para &lt;em&gt;Vibration&lt;/em&gt;. #tr00l&lt;/p&gt;

&lt;h2 id=&quot;uma_api_enorme&quot;&gt;Uma API enorme&lt;/h2&gt;

&lt;p&gt;Essa &lt;abbr title='Application Programming Interface'&gt;API&lt;/abbr&gt; é tão extensa que dá até medo, eis a listagem de todas as suas propriedades e métodos:&lt;/p&gt;

&lt;h3 id=&quot;navigatorvibrate&quot;&gt;navigator.vibrate()&lt;/h3&gt;

&lt;p&gt;Pronto. É isso. Já podemos ir pra praia? Sério, só tem esse método. Legal né? (aposto que tem muita gente comemorando agora.) De acordo com a &lt;a href=&quot;http://www.w3.org/TR/vibration/#vibration-interface&quot;&gt;spec&lt;/a&gt;, esse método recebe apenas um parâmetro que representa uma duração de tempo que o dispositivo deve permanecer vibrando.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;navigator&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;vibrate&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1000&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='c1'&gt;// vibra por 1000ms (1s)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Esse parâmetro também pode ser uma lista representando um padrão de toques, onde cada item da lista alterna entre tempo de duração de uma vibração e tempo de duração de uma intervalo. Com um exemplo fica mais fácil de entender:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;navigator&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;vibrate&lt;/span&gt;&lt;span class='p'&gt;([&lt;/span&gt;&lt;span class='mi'&gt;500&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;1000&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;800&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;500&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;1000&lt;/span&gt;&lt;span class='p'&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;No trecho acima o dispositivo começará vibrando por 500ms, depois pausa por 1000ms, vibra novamente por 800ms, pausa por 500ms e termina vibrando por mais 1000ms.&lt;/p&gt;

&lt;p&gt;Caso uma chamada de vibração já tenha sido disparada, também é possível cancelá-la passando um zero ou um &lt;em&gt;array&lt;/em&gt; vazio como parâmetro.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;navigator&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;vibrate&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='c1'&gt;// cancela qualquer vibração em execução&lt;/span&gt;
&lt;span class='nx'&gt;navigator&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;vibrate&lt;/span&gt;&lt;span class='p'&gt;([]);&lt;/span&gt; &lt;span class='c1'&gt;// mesma coisa que o anterior&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Quer testar o suporte?&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='k'&gt;if&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;vibrate&amp;#39;&lt;/span&gt; &lt;span class='k'&gt;in&lt;/span&gt; &lt;span class='nx'&gt;navigator&lt;/span&gt;&lt;span class='p'&gt;){&lt;/span&gt;
    &lt;span class='c1'&gt;// tann namm!&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;utilidades&quot;&gt;Utilidades&lt;/h2&gt;

&lt;p&gt;Tá, mas o que faço com essa &lt;abbr title='Application Programming
Interface'&gt;API&lt;/abbr&gt;? Bem, considerando que o mecanismo de vibração causa um simples &lt;em&gt;feedback&lt;/em&gt; tátil, existem algumas utilidades que podem ser de interesse para uma aplicação móvel. As mais comuns são, por exemplo, alertar o usuário ao disparar uma notificação, mensagem ou ligação e vibrar em momentos específicos ao decorrer de um jogo (uma bomba explodindo, talvez) — causando uma maior imersão para o jogador.&lt;/p&gt;

&lt;p&gt;Outras utilidades não tão óbvias poderiam ser, por exemplo, guiar um usuário portador de deficiência visual em um ambiente, onde cada tipo de vibração poderia corresponder a direcionamentos como ‘esquerda’, ‘direita’, ‘trás’, ‘frente’, etc. Um experimento que achei bastante criativo foi um &lt;a href=&quot;http://www.smartjava.org/content/html5-remotely-vibrate-phone-morse-code-using-web-sockets-and-vibrate-api&quot;&gt;comunicador em código morse&lt;/a&gt; entre dois dispositivos utilizando a &lt;abbr title='Application Programming
Interface'&gt;API&lt;/abbr&gt; de vibração e &lt;em&gt;Web Sockets&lt;/em&gt;. A partir daí vai de acordo com a criatividade de cada um.&lt;/p&gt;
&lt;table class='support'&gt;
    &lt;thead&gt;
        &lt;tr&gt;
            &lt;th class='subject'&gt;&lt;h2&gt;Suporte&lt;/h2&gt;&lt;/th&gt;
            &lt;th class='browser chrome'&gt;&lt;div class='i' /&gt;&lt;/th&gt;
            &lt;th class='browser safari'&gt;&lt;div class='i' /&gt;&lt;/th&gt;
            &lt;th class='browser firefox'&gt;&lt;div class='i' /&gt;&lt;/th&gt;
            &lt;th class='browser ie'&gt;&lt;div class='i' /&gt;&lt;/th&gt;
            &lt;th class='browser opera'&gt;&lt;div class='i' /&gt;&lt;/th&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;th /&gt;
            &lt;th class='base' colspan='5' /&gt;
        &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class='property'&gt;&lt;code&gt;navigator.vibrate()&lt;/code&gt;&lt;/td&gt;
            &lt;td&gt;32 *&lt;/td&gt;
            &lt;td&gt;--&lt;/td&gt;
            &lt;td&gt;26 *&lt;/td&gt;
            &lt;td&gt;?&lt;/td&gt;
            &lt;td&gt;--&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
    &lt;tfoot&gt;
        &lt;td colspan='6'&gt;
            * Ainda não há nenhuma informação no &lt;a href='http://caniuse.com/'&gt;caniuse&lt;/a&gt;
            à respeito da Vibration &lt;abbr title='Application Programming Interface'&gt;API&lt;/abbr&gt;,
            então fiz essa verificação nos navegadores que tenho atualmente.
        &lt;/td&gt;
    &lt;/tfoot&gt;
&lt;/table&gt;
    </content>
  </entry>
  
  <entry>
    <id>http://loopinfinito.com.br/2014/01/28/google-traceur-ecmascript-6</id>
    <title>Google Traceur, ou “Como usar ECMAScript 6 hoje”</title>
    <updated>2014-01-28T00:00:00-08:00</updated>
    <link href="http://loopinfinito.com.br/2014/01/28/google-traceur-ecmascript-6/" />
    <author>
      <name>Caio Gondim</name>
      <uri>http://twitter.com/caio_gondim</uri>
    </author>
    <content type="html">
      
      
      &lt;p&gt;&lt;img itemprop=&quot;thumbnailUrl&quot; src=&quot;http://loopinfinito.com.br/images/posts/2014-01-28-traceur.jpg&quot; alt=&quot;Google Traceur, ou “Como usar ECMAScript 6 hoje”&quot; title=&quot;Google Traceur, ou “Como usar ECMAScript 6 hoje”&quot; width=&quot;700&quot; height=&quot;432&quot; /&gt;&lt;/p&gt;
      
      
&lt;p&gt;Google Traceur é um compilador de ECMAScript 6 para o JavaScript de hoje. O seu objetivo é tornar possível o uso de &lt;em&gt;features&lt;/em&gt; da linguagem que ainda não foram implementadas na maioria dos &lt;em&gt;browsers&lt;/em&gt; e, até mesmo, outras que ainda estão sendo discutidas.&lt;/p&gt;

&lt;p&gt;Além de tornar possível o teste de &lt;em&gt;features&lt;/em&gt; da especificação do ECMAScript 6, um dos intuitos do projeto é fazer com que a comunidade participe de forma mais ativa no futuro do JavaScript, fazendo com que os desenvolvedores usem e testem hoje o que poderá vir a ser o futuro da linguagem e, assim, opinar e influenciar na nova especificação antes que esta se dê por &lt;strong&gt;fechada&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Algumas das principais &lt;em&gt;features&lt;/em&gt; suportadas hoje em dia são:&lt;/p&gt;

&lt;h3 id=&quot;classes&quot;&gt;Classes&lt;/h3&gt;

&lt;p&gt;Implementa a especificação ainda em rascunho do ECMAScript 6 sobre classes. Apenas suporta a implementação mínima, pois muito ainda está sendo discutido sobre como de fato irá ser a especificação final.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kr'&gt;class&lt;/span&gt; &lt;span class='nx'&gt;Monstro&lt;/span&gt; &lt;span class='kr'&gt;extends&lt;/span&gt; &lt;span class='nx'&gt;Personagem&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;constructor&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;x&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;y&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;nome&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='kr'&gt;super&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;x&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;y&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;nome&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;nome&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;life_&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;100&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;

  &lt;span class='nx'&gt;ataca&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;personagem&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='kr'&gt;super&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attack&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;personagem&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;

  &lt;span class='nx'&gt;get&lt;/span&gt; &lt;span class='nx'&gt;isVivo&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;life_&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
  &lt;span class='nx'&gt;get&lt;/span&gt; &lt;span class='nx'&gt;life&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;life_&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
  &lt;span class='nx'&gt;set&lt;/span&gt; &lt;span class='nx'&gt;life&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;valor&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;valor&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='k'&gt;throw&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nb'&gt;Error&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;Life não pode ser negativo.&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;

    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;life_&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;valor&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Reparem no código acima que temos alguns elementos comuns em linguagens orientadas a objeto como: uma função construtora, herança e uma palavra reservada para chamarmos a classe pai. Além disso, as definições dos métodos não necessitam ser declarados com &lt;code&gt;function&lt;/code&gt; como uma função normal e podemos também definir métodos &lt;code&gt;get&lt;/code&gt; e &lt;code&gt;set&lt;/code&gt; para atributos que irão ser chamados quando passarmos um novo valor para um atributo ou pedirmos seu valor atual.&lt;/p&gt;

&lt;h3 id=&quot;destructuring_assignment&quot;&gt;Destructuring Assignment&lt;/h3&gt;

&lt;p&gt;Um atalho para inicializar ou definir várias variáveis de uma só vez.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;ponto&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;x&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;y&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;retangulo&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;topLeft&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;x&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;y&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;4&lt;/span&gt;&lt;span class='p'&gt;},&lt;/span&gt; &lt;span class='nx'&gt;bottomRight&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;x&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;y&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='p'&gt;}}&lt;/span&gt;

&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;x&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;y&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;ponto&lt;/span&gt; &lt;span class='c1'&gt;// descompacta o ponto&lt;/span&gt;
&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;x&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;y&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='c1'&gt;// imprime 1 2&lt;/span&gt;

&lt;span class='c1'&gt;// descompacta o retângulo&lt;/span&gt;
&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;topLeft&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;x&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nx'&gt;x1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;y&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nx'&gt;y1&lt;/span&gt;&lt;span class='p'&gt;},&lt;/span&gt; &lt;span class='nx'&gt;bottomRight&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;x&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nx'&gt;x2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;y&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nx'&gt;y2&lt;/span&gt;&lt;span class='p'&gt;}}&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;retangulo&lt;/span&gt;
&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;x1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;y1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;x2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;y2&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='c1'&gt;// imprime 3 4 5 6&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;block_scoped_bindings&quot;&gt;Block scoped bindings&lt;/h3&gt;

&lt;p&gt;Aqui temos escopo a nível de bloco, e não mais apenas a nível de função e global. Isto assegura que as variáveis não vazem de um escopo sem a necessidade de usarmos &lt;a href=&quot;https://github.com/caiogondim/js-patterns-sublime-snippets#immediate-function&quot;&gt;funções de execução imediata&lt;/a&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='kr'&gt;const&lt;/span&gt; &lt;span class='nx'&gt;salario&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;750&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
  &lt;span class='nx'&gt;nome&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;n3rd&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
  &lt;span class='nx'&gt;sobrenome&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;l33t&amp;#39;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='c1'&gt;// não é acessível fora do escopo do objeto onde foi definido&lt;/span&gt;
&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;salario&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As palavras reservadas &lt;code&gt;const&lt;/code&gt; e &lt;code&gt;let&lt;/code&gt; são, até o momento, as únicas que possuem esse comportamento de escopo em bloco.&lt;/p&gt;

&lt;h3 id=&quot;parmetros_default&quot;&gt;Parâmetros default&lt;/h3&gt;

&lt;p&gt;Tão óbvio que os novatos em JS nem conseguem acreditar que não existe um meio de definirmos valores &lt;em&gt;default&lt;/em&gt; para parâmetros. Finalmente agora é possível.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;foo&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;a&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;b&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;c&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='c1'&gt;// ...&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='nx'&gt;foo&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='c1'&gt;// a = 3, b = 2, c = 3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;rest_parameters&quot;&gt;Rest parameters&lt;/h3&gt;

&lt;p&gt;Permite que funções tenham um número variável de parâmetros sem a necessidade do uso do objeto &lt;code&gt;arguments&lt;/code&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;ouro&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;prata&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;restante&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;desconhecido&amp;#39;&lt;/span&gt;

&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;concedeMedalha&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;primeiro&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;segundo&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='p'&gt;...&lt;/span&gt;&lt;span class='nx'&gt;outros&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;ouro&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;primeiro&lt;/span&gt;
  &lt;span class='nx'&gt;prata&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;segundo&lt;/span&gt;
  &lt;span class='nx'&gt;restante&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;outros&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='nx'&gt;concedeMedalha&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;Michael Phelps&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;Liu Xiang&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;Yao Ming&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;Allyson Felix&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;ouro&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='c1'&gt;// imprime “Michael Phelps”&lt;/span&gt;
&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;prata&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='c1'&gt;// imprime “Liu Xiang”&lt;/span&gt;
&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;restante&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;join&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;, &amp;#39;&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='c1'&gt;// imprime o “Yao Ming, Allyson Felix”&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;spread_operator&quot;&gt;Spread operator&lt;/h3&gt;

&lt;p&gt;O &lt;em&gt;spread operator&lt;/em&gt; é como o inverso do &lt;em&gt;rest parameters&lt;/em&gt;. Ele expande um &lt;em&gt;array&lt;/em&gt; em em argumentos formais. Continuando com o exemplo acima, imaginem que agora, no lugar de passarmos um a um os competidores para a função &lt;code&gt;concedeMedalha&lt;/code&gt;, pudessemos passar um &lt;em&gt;array&lt;/em&gt; e cada posição desse &lt;em&gt;array&lt;/em&gt; ser interpretado como um argumento.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;ouro&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;prata&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;restante&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;desconhecido&amp;#39;&lt;/span&gt;

&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;concedeMedalha&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;primeiro&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;segundo&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='p'&gt;...&lt;/span&gt;&lt;span class='nx'&gt;outros&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;ouro&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;primeiro&lt;/span&gt;
  &lt;span class='nx'&gt;prata&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;segundo&lt;/span&gt;
  &lt;span class='nx'&gt;restante&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;outros&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;competidores&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;
  &lt;span class='s1'&gt;&amp;#39;Michael Phelps&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
  &lt;span class='s1'&gt;&amp;#39;Liu Xiang&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
  &lt;span class='s1'&gt;&amp;#39;Yao Ming&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
  &lt;span class='s1'&gt;&amp;#39;Allyson Felix&amp;#39;&lt;/span&gt;
&lt;span class='p'&gt;]&lt;/span&gt;

&lt;span class='nx'&gt;concedeMedalha&lt;/span&gt;&lt;span class='p'&gt;(...&lt;/span&gt;&lt;span class='nx'&gt;competidores&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;ouro&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='c1'&gt;// imprime “Michael Phelps”&lt;/span&gt;
&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;prata&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='c1'&gt;// imprime “Liu Xiang”&lt;/span&gt;
&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;restante&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;join&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;, &amp;#39;&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='c1'&gt;// imprime o “Yao Ming, Allyson Felix”&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;atalho_para_inicializar_objeto&quot;&gt;Atalho para inicializar objeto&lt;/h3&gt;

&lt;p&gt;Evita o repetitivo código &lt;code&gt;{x: x, y: y, z: z}&lt;/code&gt; quando estamos definindo um objeto cujo a chave possui o valor da variável de mesmo nome.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;obj&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;x&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;y&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='c1'&gt;// um atalho para o código acima&lt;/span&gt;
&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;obj&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;x&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nx'&gt;x&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;y&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nx'&gt;y&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;f&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;x&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;y&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;x&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nx'&gt;x&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;y&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nx'&gt;y&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='c1'&gt;// o mesmo que o código acima&lt;/span&gt;
&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;f&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;x&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;y&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;x&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;y&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Reparem que na primeira linha do trecho de código acima, inicializamos a variável &lt;code&gt;obj&lt;/code&gt; com o valor &lt;code&gt;{x, y}&lt;/code&gt;, o que é sintaticamente errado no ECMAScript 3. O que este “atalho” faz é &lt;em&gt;setar&lt;/em&gt; um objeto com chave &lt;code&gt;x&lt;/code&gt; com o valor da variável &lt;code&gt;x&lt;/code&gt;. Falando em JS, ele evita que você digite repetidamente este trecho: &lt;code&gt;var obj = {x: x, y: y}&lt;/code&gt;, dando um atalho para tal, desta forma: &lt;code&gt;var obj = {x, y}&lt;/code&gt;. Dificil de explicar, mas fácil de entender. Tenta acompanhar esse outro exemplo.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;nome&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Joao&amp;quot;&lt;/span&gt;
&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;sobrenome&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Silva&amp;quot;&lt;/span&gt;

&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;pessoa&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;nome&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;sobrenome&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='c1'&gt;// o mesmo que `var pessoa = {nome: nome, sobrenome: sobrenome}`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;property_method_assignment&quot;&gt;Property method assignment&lt;/h3&gt;

&lt;p&gt;Permite que métodos de objetos sejam definidos de uma maneira mais clara. Reparem que, abaixo, definimos os métodos &lt;code&gt;bunizar&lt;/code&gt; e &lt;code&gt;ligar&lt;/code&gt; sem usar a palavra-reservada &lt;code&gt;function&lt;/code&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;carro&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;nome&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;Lorem&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
  &lt;span class='nx'&gt;marca&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;Ipsum&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
  &lt;span class='nx'&gt;buzinar&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='c1'&gt;// ...&lt;/span&gt;
  &lt;span class='p'&gt;},&lt;/span&gt;
  &lt;span class='nx'&gt;ligar&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='c1'&gt;// ...&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Isto é, até o momento, o que o Google Traceur suporta sobre &lt;em&gt;Property method assignment&lt;/em&gt;. Porém a &lt;a href=&quot;http://wiki.ecmascript.org/doku.php?id=harmony:concise_object_literal_extensions#methods&quot;&gt;especificação&lt;/a&gt; abrange mais detalhes.&lt;/p&gt;

&lt;h3 id=&quot;e_mais&quot;&gt;E mais…&lt;/h3&gt;

&lt;p&gt;Existem mais algumas &lt;em&gt;features&lt;/em&gt; que o o Google Traceur suporta, como &lt;a href=&quot;https://github.com/google/traceur-compiler/wiki/LanguageFeatures#promises&quot;&gt;promises&lt;/a&gt;, &lt;a href=&quot;https://github.com/google/traceur-compiler/wiki/LanguageFeatures#iterators-and-for-of-loops&quot;&gt;iterators&lt;/a&gt;, &lt;a href=&quot;https://github.com/google/traceur-compiler/wiki/LanguageFeatures#generators&quot;&gt;generatos&lt;/a&gt; e outros. Optei por abranger as mais consolidadas na especificação e de mais fácil entendimento, caso contrário este &lt;em&gt;post&lt;/em&gt; iria virar uma bíblia. A quem quiser descer na toca do coelho, aconselho a &lt;a href=&quot;https://github.com/google/traceur-compiler/wiki/LanguageFeatures&quot;&gt;Wiki do projeto&lt;/a&gt; e, claro, a própria &lt;a href=&quot;http://wiki.ecmascript.org/doku.php?id=harmony:harmony&quot;&gt;especificação do ECMAScript 6&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;integrando_no_grunt&quot;&gt;Integrando no Grunt&lt;/h2&gt;
&lt;figure&gt;
  &lt;img alt='Pixel Referência' height='300' src='http://loopinfinito.com.br/images/posts/2014-01-28-grunt.jpg' width='700' /&gt;
&lt;/figure&gt;
&lt;p&gt;E como já dizia Steve Jobs: “There is a Grunt task for that!”. Integrar o processo de tradução/compilação/transpilação de ECMAScript 6 para o JS de hoje fica fácil com o Grunt. Vamos usar o pacote &lt;strong&gt;grunt-traceur&lt;/strong&gt; para tal.&lt;/p&gt;

&lt;p&gt;No terminal, entre na pasta do seu projeto e vamos instalar todos os pacotes necessários. Primeiro vamos instalar o Grunt e, logo em seguida, o grunt- traceur.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;npm install -g grunt-cli
npm install grunt --save-dev
npm install grunt-traceur --save-dev
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Algumas considerações sobre os comandos usados acima: a &lt;em&gt;flag&lt;/em&gt; &lt;code&gt;-g&lt;/code&gt; usada para instalar o Grunt é para que o &lt;strong&gt;grunt-cli&lt;/strong&gt; seja instalado de forma global, que é um passo necessário para usar o grunt no terminal sem informamos o &lt;code&gt;PATH&lt;/code&gt; do seu executável; a &lt;em&gt;flag&lt;/em&gt; &lt;code&gt;--save-dev&lt;/code&gt; para que as dependências sejam automaticamente inseridas no seu arquivo &lt;strong&gt;package.json&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Com Grunt e grunt-traceur instalados, agora podemos configurar nosso Gruntfile. Crie um arquivo chamado &lt;strong&gt;Gruntfile.js&lt;/strong&gt; (ou Gruntfile.coffee) na raíz do seu projeto. Abaixo um exemplo de um Gruntfile.js completo. Caso você já possua um, extraia apenas as partes relacionadas ao grunt-traceur.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;module&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;exports&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;grunt&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='s1'&gt;&amp;#39;use strict&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

  &lt;span class='nx'&gt;grunt&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;loadNpmTasks&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;grunt-traceur&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;gruntConfig&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{}&lt;/span&gt;

  &lt;span class='nx'&gt;gruntConfig&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;traceur&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;options&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;blockBinding&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kc'&gt;true&lt;/span&gt; &lt;span class='c1'&gt;// habilita `let` e `const`&lt;/span&gt;
    &lt;span class='p'&gt;},&lt;/span&gt;
    &lt;span class='nx'&gt;custom&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;files&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='s1'&gt;&amp;#39;static/app.js&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;
          &lt;span class='s1'&gt;&amp;#39;assets/character.js&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
          &lt;span class='s1'&gt;&amp;#39;assets/monster.js&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
          &lt;span class='s1'&gt;&amp;#39;assets/main.js&amp;#39;&lt;/span&gt;
        &lt;span class='p'&gt;]&lt;/span&gt;
      &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;

  &lt;span class='nx'&gt;grunt&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;initConfig&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;gruntConfig&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;No objeto &lt;code&gt;files&lt;/code&gt; passamos como chave o arquivo de &lt;em&gt;output&lt;/em&gt; e como valor um &lt;em&gt;array&lt;/em&gt; com todos os arquivos que serão compilados, em ordem. No exemplo acima, os arquivos &lt;code&gt;assets/character.js&lt;/code&gt;, &lt;code&gt;assets/monster.js&lt;/code&gt; e &lt;code&gt;assets/main.js&lt;/code&gt; serão todos compilados e concatenados no arquivo &lt;code&gt;static/app.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Agora basta rodar no seu terminal o comando &lt;code&gt;grunt traceur&lt;/code&gt; toda vez que você modificar seus arquivos JavaScript.&lt;/p&gt;

&lt;p&gt;Mas isso obviamente vai ficar muito chato depois da terceira vez que você tiver que mudar para o terminal e digitar manualmente &lt;code&gt;grunt traceur&lt;/code&gt;. Para deixar esse processo de &lt;em&gt;build&lt;/em&gt; mais automatizado: “There is a Grunt task for that”.&lt;/p&gt;

&lt;p&gt;Vamos usar a &lt;em&gt;task&lt;/em&gt; watch do Grunt para que toda vez que modificarmos os arquivos JS escritos em ECMAScript 6, eles sejam compilados para o JavaScript de hoje.&lt;/p&gt;

&lt;p&gt;Para instalar o pacote &lt;strong&gt;grunt-watch&lt;/strong&gt; digite no seu terminal o comando abaixo:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;npm install grunt-watch --save-dev
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;E agora vamos configurar a &lt;em&gt;task&lt;/em&gt;. Vamos adicionar um objeto &lt;code&gt;watch&lt;/code&gt; ao nosso objeto de configuração do Grunt.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;grunt&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;loadNpmTasks&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;grunt-watch&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

&lt;span class='nx'&gt;gruntConfig&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;watch&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;traceur&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;files&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;./caminho/para/arquivos/ecmascript6/*.js&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
    &lt;span class='nx'&gt;tasks&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;traceur&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Com isso, basta rodarmos no terminal o comando &lt;code&gt;grunt watch:traceur&lt;/code&gt; e, toda vez que um arquivo for modificado, ele será traduzido/compilado/transpilado para o JavaScript compatível hoje na maioria dos &lt;em&gt;browsers&lt;/em&gt;.&lt;/p&gt;

&lt;h2 id=&quot;integrando_no_gulp&quot;&gt;Integrando no Gulp&lt;/h2&gt;
&lt;figure&gt;
  &lt;img alt='Gulp' height='300' src='http://loopinfinito.com.br/images/posts/2014-01-28-gulp.png' width='700' /&gt;
&lt;/figure&gt;
&lt;p&gt;E se você, JS hipster, acha o Grunt uma ferramenta muito &lt;em&gt;mainstream&lt;/em&gt;, não se preocupe: também existe um módulo para Gulp. Ele foi escrito pelo &lt;a href=&quot;https://github.com/sindresorhus/&quot;&gt;@sindresorhus&lt;/a&gt; e você pode ver mais detalhes do pacote na &lt;a href=&quot;https://github.com/sindresorhus/gulp-traceur&quot;&gt;página do projeto no GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Instruções para instalar? Se você usar o Gulp com certeza não precisa de instruções para instalar. Você lê o código diretamente, não é isso?&lt;/p&gt;

    </content>
  </entry>
  
  <entry>
    <id>http://loopinfinito.com.br/2014/01/08/css-transform-2d-interativo</id>
    <title>CSS Transform'ers 2D Interativo</title>
    <updated>2014-01-08T00:00:00-08:00</updated>
    <link href="http://loopinfinito.com.br/2014/01/08/css-transform-2d-interativo/" />
    <author>
      <name>Caio Gondim</name>
      <uri>http://twitter.com/caio_gondim</uri>
    </author>
    <content type="html">
      
      
      &lt;p&gt;&lt;img itemprop=&quot;thumbnailUrl&quot; src=&quot;http://loopinfinito.com.br/images/posts/2014-01-08-css-transform.jpg&quot; alt=&quot;CSS Transform'ers 2D Interativo&quot; title=&quot;CSS Transform'ers 2D Interativo&quot; width=&quot;700&quot; height=&quot;432&quot; /&gt;&lt;/p&gt;
      
      
&lt;p&gt;Há pouco tempo li o excelente livro &lt;a href=&quot;http://csstransforms.com/&quot;&gt;CSS Transforms: An Interactive Guide&lt;/a&gt; escrito pela &lt;a href=&quot;http://twitter.com/vickimurley&quot;&gt;Vicki Murley&lt;/a&gt;, uma evangelista web ex-Apple. Esta foi uma das &lt;strong&gt;melhores&lt;/strong&gt; e mais &lt;strong&gt;fáceis&lt;/strong&gt; leituras que já fiz relacionado a CSS. Além de tratar com muito domínio sobre o assunto, o que mais me chamou atenção foi o modo como é demonstrado cada nova função, tornando um assunto por vezes muito abstrato em algo prático e fácil de ser entendido.&lt;/p&gt;

&lt;p&gt;Então, fortemente inspirado em seu livro, vou agora tentar explicar CSS Transforms de um modo similar ao modo que Vicki aborda em seu livro e, também, da mesma forma que sempre tentamos fazer por aqui: &lt;strong&gt;na prática&lt;/strong&gt;.&lt;/p&gt;

&lt;h2 id=&quot;breve_introduo&quot;&gt;Breve introdução&lt;/h2&gt;

&lt;p&gt;Com o lançamento do primeiro iPhone em 2007, seu rápido ganho em popularidade e sua &lt;strong&gt;falta de suporte ao Adobe Flash&lt;/strong&gt;, ficou claro que era necessário uma tecnologia &lt;em&gt;web&lt;/em&gt; nativa — sem &lt;em&gt;plug-ins&lt;/em&gt; de terceiros — para animações mais avançadas e de alta performance. Então, no mesmo ano de 2007, um engenheiro da Apple enviou para a &lt;em&gt;mailing list&lt;/em&gt; da &lt;abbr title='World Wide Web Consortium'&gt;W3C&lt;/abbr&gt; a proposta para CSS Transforms. Esta especificação foi primeiramente implementada no WebKit, pois era de interesse da Apple, mas foi ganhando popularidade aos poucos, por se mostrar uma tecnologia mais performática, livre e &lt;em&gt;cross-browser&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Hoje o CSS Transforms já está implementado em todos os grandes navegadores e seu uso em produção é bem comum e, inclusive, aconselhado. Ele torna possível adicionarmos efeitos visuais à &lt;em&gt;web&lt;/em&gt; que antes só podiam ser implementados através de &lt;em&gt;plug-ins&lt;/em&gt; de terceiros. Também servem de base para animações mais complexas e podem ser aplicados em qualquer elemento HTML. E são eles que vamos estudar e experimentar na prática como funcionam.&lt;/p&gt;

&lt;h2 id=&quot;translate&quot;&gt;Translate&lt;/h2&gt;

&lt;p&gt;A função &lt;code&gt;translate&lt;/code&gt; é usada para &lt;strong&gt;movermos&lt;/strong&gt; um elemento nos eixos X, Y, ou ambos. Caso seja passado apenas um parâmetro para a função, o elemento será movido em relação ao eixo X. Já com dois parâmetros, o primeiro será o valor usado para a movimentação no eixo X, e o segundo para o eixo Y.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='css'&gt;&lt;span class='nt'&gt;img&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='n'&gt;transform&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;translate&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='m'&gt;13px&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='m'&gt;10px&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='c'&gt;/* move elemento 13px em X e 10px em Y */&lt;/span&gt;
  &lt;span class='n'&gt;transform&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;translate&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='m'&gt;13px&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='c'&gt;/* move elemento 13px no eixo X */&lt;/span&gt;
  &lt;span class='n'&gt;transform&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;translateX&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='m'&gt;13px&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='c'&gt;/* move elemento 13px no eixo X */&lt;/span&gt;
  &lt;span class='n'&gt;transform&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;translateY&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='m'&gt;10px&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='c'&gt;/* move elemento 10px no eixo Y */&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Além de &lt;code&gt;px&lt;/code&gt;, também podemos passar valores expressos em &lt;code&gt;%&lt;/code&gt;. Neste caso, 100% será equivalente a dimensão do elemento no eixo em que vamos efetuar o &lt;code&gt;translate&lt;/code&gt;. Em outras palavras: se vamos movimentar o elemento no eixo X, 100% será igual a sua largura; se a movimentação ocorrer no eixo Y, 100% equivalerá a altura do elemento. No experimento abaixo vocês podem ver a função &lt;code&gt;translate&lt;/code&gt; em ação de uma forma mais interativa e menos abstrata, basta mover os &lt;em&gt;handlers&lt;/em&gt; dos &lt;em&gt;inputs&lt;/em&gt; do Translate X e Translate Y.&lt;/p&gt;
&lt;iframe class='img' frameborder='0' height='432' src='http://caiogondim.github.io/css-transform-interactive/#translate' width='700'&gt;
&amp;nbsp;
&lt;/iframe&gt;
&lt;p&gt;Reparem que valores negativos também são aceitos. Valores negativos em X movimentam o elemento para a esquerda. Valores negativos em Y movimentam o elemento para cima. Um &lt;code&gt;transform: translateX(-10px);&lt;/code&gt; moverá o elemento 10 &lt;em&gt;pixels&lt;/em&gt; para a esquerda. Enquanto um &lt;code&gt;transform: translateY(-5px);&lt;/code&gt; moverá o elemento 5 &lt;em&gt;pixels&lt;/em&gt; para cima.&lt;/p&gt;

&lt;h2 id=&quot;skew&quot;&gt;Skew&lt;/h2&gt;

&lt;p&gt;A função &lt;code&gt;skew&lt;/code&gt; irá &lt;strong&gt;“entortar”&lt;/strong&gt; um elemento em relação a um dos eixos.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='css'&gt;&lt;span class='nt'&gt;img&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='n'&gt;transform&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;skewX&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='m'&gt;30&lt;/span&gt;&lt;span class='n'&gt;deg&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='c'&gt;/* “entorta” o elemento horizontalmente */&lt;/span&gt;
  &lt;span class='n'&gt;transform&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;skewY&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='m'&gt;30&lt;/span&gt;&lt;span class='n'&gt;deg&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='c'&gt;/* “entorta” o elemento verticalmente */&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As funções usadas para efetuarmos o &lt;em&gt;skew&lt;/em&gt; são &lt;code&gt;skewX&lt;/code&gt; e &lt;code&gt;skewY&lt;/code&gt;. Cada uma recebe apenas um parâmetro, estes expressos em graus (&lt;code&gt;deg&lt;/code&gt;). No experimento abaixo fica bem mais fácil entender o que acontece quando aplicamos o &lt;code&gt;skew&lt;/code&gt;. Assim como no experimento acima, basta mover os &lt;em&gt;handlers&lt;/em&gt; da parte esquerda inferior para alterar os valores e ver o efeito desta mudança na direita.&lt;/p&gt;
&lt;iframe class='img' frameborder='0' height='432' src='http://caiogondim.github.io/css-transform-interactive/#skew' width='700'&gt;
&amp;nbsp;
&lt;/iframe&gt;
&lt;p&gt;Também existe uma função &lt;code&gt;skew&lt;/code&gt;, que, na teoria, funcionaria como um atalho para as funções &lt;code&gt;skewX&lt;/code&gt; e &lt;code&gt;skewY&lt;/code&gt;. Mas o seu resultado final não é o mesmo que o das funções &lt;code&gt;skewX&lt;/code&gt; e &lt;code&gt;skewY&lt;/code&gt; usadas de forma separada com os mesmos parâmetros de &lt;code&gt;skew&lt;/code&gt;. O próprio &lt;abbr title='Mozilla Developer Network'&gt;MDN&lt;/abbr&gt;  &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function&quot;&gt;desaconselha seu uso&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;rotate&quot;&gt;Rotate&lt;/h2&gt;

&lt;p&gt;A função &lt;code&gt;rotate&lt;/code&gt; … &lt;strong&gt;rotaciona&lt;/strong&gt;. Simples assim. Ela recebe um único parâmetro que pode ser expresso em graus (&lt;code&gt;deg&lt;/code&gt;), radianos (&lt;code&gt;rad&lt;/code&gt;) ou voltas (&lt;code&gt;turn&lt;/code&gt;).&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='css'&gt;&lt;span class='nt'&gt;img&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='n'&gt;transform&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;rotate&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='m'&gt;30&lt;/span&gt;&lt;span class='n'&gt;deg&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='c'&gt;/* rotaciona 30&amp;#39; no sentido horário */&lt;/span&gt;
  &lt;span class='n'&gt;transform&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;rotate&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='m'&gt;-45&lt;/span&gt;&lt;span class='n'&gt;deg&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='c'&gt;/* rotaciona 45&amp;#39; no sentido anti-horário */&lt;/span&gt;
  &lt;span class='n'&gt;transform&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;rotate&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='m'&gt;2&lt;/span&gt;&lt;span class='n'&gt;rad&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='c'&gt;/* rotaciona ~ 144,59&amp;#39; no sentido horário */&lt;/span&gt;
  &lt;span class='n'&gt;transform&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;rotate&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='m'&gt;0&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='m'&gt;5&lt;/span&gt;&lt;span class='n'&gt;turn&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='c'&gt;/* rotaciona meia-volta no sentido horário */&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Valores positivos rotacionam o elemento no sentido horário, enquanto que valores negativos rotacionam o elemento no sentido anti-horário. O experimento abaixo mostra o &lt;code&gt;rotate&lt;/code&gt; em ação.&lt;/p&gt;
&lt;iframe class='img' frameborder='0' height='432' src='http://caiogondim.github.io/css-transform-interactive/#rotate' width='700'&gt;
&amp;nbsp;
&lt;/iframe&gt;
&lt;h2 id=&quot;scale&quot;&gt;Scale&lt;/h2&gt;

&lt;p&gt;Altera o &lt;strong&gt;tamanho&lt;/strong&gt; do elemento em ambos os eixos ou apenas em um eixo específico. Esta função aceita um ou dois parâmetros. Caso seja passado apenas um, a alteração irá ocorrer tanto na altura como na largura. Caso sejam passados dois, o primeiro argumento irá alterar a largura e o segundo irá alterar a altura.&lt;/p&gt;

&lt;p&gt;Os valores passados como parâmetros não possuem unidades. Eles funcionam como “multiplicadores” do tamanho do elemento. Um &lt;code&gt;transform: scale(2)&lt;/code&gt; irá duplicar o tamanho do elemento. Um &lt;code&gt;transform: scale(0.5)&lt;/code&gt; irá reduzi-lo pela metade.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='css'&gt;&lt;span class='nt'&gt;img&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='n'&gt;transform&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;scale&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='m'&gt;2&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='c'&gt;/* dobra o tamanho do elemento em todas as direções */&lt;/span&gt;
  &lt;span class='n'&gt;transform&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;scale&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='m'&gt;2&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='m'&gt;3&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='c'&gt;/* dobra a largura e triplica a altura */&lt;/span&gt;
  &lt;span class='n'&gt;transform&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;scaleX&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='m'&gt;0&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='m'&gt;5&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='c'&gt;/* reduz largura do elemento pela metade */&lt;/span&gt;
  &lt;span class='n'&gt;transform&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;scaleY&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='m'&gt;2&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='c'&gt;/* deixa o elemento duas vezes mais alto */&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Além da função &lt;code&gt;scale&lt;/code&gt;, podemos usar as funções específicas de cada eixo: para o eixo X a &lt;code&gt;scaleX&lt;/code&gt; e para o eixo Y a &lt;code&gt;scaleY&lt;/code&gt;. Abaixo também podemos interagir com esta função e ver na prática como se comporta.&lt;/p&gt;
&lt;iframe class='img' frameborder='0' height='432' src='http://caiogondim.github.io/css-transform-interactive/#scale' width='700'&gt;
&amp;nbsp;
&lt;/iframe&gt;
&lt;p&gt;Observem no experimento acima que, ao passarmos valores negativos, nós invertemos a imagem. Se passarmos um valor de -1 para &lt;code&gt;scaleX&lt;/code&gt;, é como se estivéssemos espelhando o elemento. -1 para &lt;code&gt;scaleY&lt;/code&gt; e o elemento irá ficar de cabeça para baixo (invertido na vertical).&lt;/p&gt;

&lt;h2 id=&quot;mltiplas_transformaes&quot;&gt;Múltiplas transformações&lt;/h2&gt;

&lt;p&gt;É possível usar várias funções &lt;code&gt;transform&lt;/code&gt; ao mesmo tempo em um elemento. Para isso, é só declarar todas as funções — com seus devidos valores — separados por um espaço.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='css'&gt;&lt;span class='nt'&gt;img&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='n'&gt;transform&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;translateX&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='m'&gt;2px&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='n'&gt;transform&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;skewX&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='m'&gt;45&lt;/span&gt;&lt;span class='n'&gt;deg&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='c'&gt;/* sobrescreve a transformação acima */&lt;/span&gt;
  &lt;span class='n'&gt;transform&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;rotate&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='m'&gt;0&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='m'&gt;5&lt;/span&gt;&lt;span class='n'&gt;turn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='n'&gt;scale&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='m'&gt;2&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='c'&gt;/* rotaciona em 180º e duplica o tamanho */&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Cuidado para não declarar várias regras &lt;code&gt;transform&lt;/code&gt; no mesmo elemento, pois dessa forma a última regra sobrescreve todas as outras declaradas&lt;/p&gt;
&lt;table class='support'&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th class='subject'&gt;&lt;h2&gt;Suporte&lt;/h2&gt;&lt;/th&gt;
      &lt;th class='browser chrome'&gt;&lt;div class='i' /&gt;&lt;/th&gt;
      &lt;th class='browser safari'&gt;&lt;div class='i' /&gt;&lt;/th&gt;
      &lt;th class='browser firefox'&gt;&lt;div class='i' /&gt;&lt;/th&gt;
      &lt;th class='browser ie'&gt;&lt;div class='i' /&gt;&lt;/th&gt;
      &lt;th class='browser opera'&gt;&lt;div class='i' /&gt;&lt;/th&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th /&gt;
      &lt;th class='base' colspan='5' /&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td class='property'&gt;transform&lt;/td&gt;
      &lt;td&gt;4 &lt;code class='small'&gt;-webkit-&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;3.1 &lt;code class='small'&gt;-webkit-&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;3.5&lt;/td&gt;
      &lt;td&gt;9.0&lt;/td&gt;
      &lt;td&gt;10.5 &lt;code class='small'&gt;-webkit-&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Com a exceção do Internet Explorer (alguém surpreso?), o CSS Transform já é suportado nos principais &lt;em&gt;browsers&lt;/em&gt; há muito tempo. O &lt;abbr title='Internet Explorer'&gt;IE&lt;/abbr&gt; só veio dar suporte na sua versão 9.0.&lt;/p&gt;

&lt;p&gt;E para quem quiser se aprofundar mais no assunto, aconselho fortemente que comprem o livro &lt;a href=&quot;http://csstransforms.com/&quot;&gt;&lt;strong&gt;CSS Transforms: An Interactive Guide&lt;/strong&gt;&lt;/a&gt; da Vicki Murley. Nele, além de CSS Transforms 2D, também é abordado o assunto CSS Transforms 3D.&lt;/p&gt;

&lt;p&gt;O código de todos os experimentos acima estão, como de costume, disponíveis no &lt;a href=&quot;https://github.com/caiogondim/css-transform-interactive&quot;&gt;Github&lt;/a&gt;. Gostou? Dá uma estrela pro projeto =).&lt;/p&gt;

    </content>
  </entry>
  
</feed>