{"id":3697,"date":"2014-11-06T11:21:07","date_gmt":"2014-11-06T13:21:07","guid":{"rendered":"http:\/\/blog.turbosite.com.br\/?p=3697"},"modified":"2014-11-06T11:21:07","modified_gmt":"2014-11-06T13:21:07","slug":"javascript-iife-como-conteiner-de-codigos","status":"publish","type":"post","link":"https:\/\/www.turbosite.com.br\/blog\/javascript-iife-como-conteiner-de-codigos\/","title":{"rendered":"JavaScript IIFE como cont\u00eainer de c\u00f3digos"},"content":{"rendered":"<p>Encontramos uma postagem interessante sobre Javascript\u00a0IIFE\u00a0no blog\u00a0<a href=\"http:\/\/desenvolvimentoparaweb.com\/javascript\/javascript-iife-conteiner-de-codigos\/\">Desenvolvimento Para Web<\/a>, que explica em muitos detalhes a sintaxe e as funcionalidades\u00a0do IIFE. A equipe da <a href=\"https:\/\/www.turbosite.com.br\/\">Turbosite<\/a> repassa esse conhecimento para os leitores do nosso blog, com a postagem a seguir.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>JavaScript puro<\/strong> ou <em>Vanilla JavaScript<\/em> (felizmente) est\u00e1 voltando. E com for\u00e7a. Mas, quando voc\u00ea decide continuar nos estudos e come\u00e7a a inspecionar c\u00f3digos alheios, inevitavelmente voc\u00ea se depara com algo como:<\/p>\n<div class=\"wp_syntax\">\n<pre class=\"lang:js decode:true\">(function (window, document, undefined) {\n    \/\/\n})(window, document);<\/pre>\n<p>E voc\u00ea encontra isso em diversos c\u00f3digos; e v\u00ea outros desenvolvedores indicando; e colegas dizendo que esta \u00e9 uma boa pr\u00e1tica. Mas voc\u00ea sabe o que, realmente, isso significa? Continue lendo.<\/p>\n<p>&nbsp;<\/p>\n<\/div>\n<p>Frequentemente desenvolvedores descobrindo (ou redescobrindo) o JavaScript puro se perguntam sobre <strong>IIFE<\/strong> (Express\u00e3o de Fun\u00e7\u00e3o Imediatamente Invocada ou <em>Immediately-Invoked Function Expression<\/em>), frequentemente apresentado da seguinte maneira:<\/p>\n<div class=\"wp_syntax\">\n<pre class=\"lang:js decode:true\">(function (window, document, undefined) {\n    \/\/\n})(window, document);<\/pre>\n<p>Na verdade, v\u00e1rias coisas est\u00e3o acontecendo a\u00ed. Analisemos cada uma delas.<\/p>\n<p>&nbsp;<\/p>\n<\/div>\n<h2>Escopo privado em IIFE<\/h2>\n<p>JavaScript tem maneiras interessantes de trabalhar com escopo de fun\u00e7\u00e3o; ent\u00e3o, primeiramente essa express\u00e3o cria um \u201c\u00e2mbito privado\u201d (private scope). Por exemplo:<\/p>\n<div class=\"wp_syntax\">\n<pre class=\"lang:js decode:true\">(function (window, document, undefined) {\n    var name = 'Foo';\n})(window, document);\nconsole.log(name); \/\/ \"name\" n\u00e3o definido, est\u00e1 em um escopo diferente<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<h2>Como funciona IIFE<\/h2>\n<p>Uma fun\u00e7\u00e3o normal se parece com isso:<\/p>\n<div class=\"wp_syntax\">\n<pre class=\"lang:js decode:true\">var logMyName = function (name) {\n    console.log(name);\n};\nlogMyName('Foo');<\/pre>\n<\/div>\n<p>Ela \u00e9 chamada (<em>invoke<\/em>) quando necess\u00e1rio, por escolha do programador, em qualquer ponto do c\u00f3digo em que se queira e\/ou seja poss\u00edvel.<\/p>\n<p>A raz\u00e3o pela qual essa <strong>IIFE em JavaScript<\/strong> foi criada, foi para ser uma express\u00e3o de fun\u00e7\u00e3o imediatamente invocada, o que significa que elas s\u00e3o imediatamente chamadas em tempo de execu\u00e7\u00e3o \u2013 tamb\u00e9m, n\u00e3o \u00e9 poss\u00edvel cham\u00e1-la novamente, j\u00e1 que elas s\u00f3 rodam uma vez, mais ou menos assim:<\/p>\n<div class=\"wp_syntax\">\n<pre class=\"lang:js decode:true\">var logMyName = (function (name) {\n    console.log(name); \/\/ Todd\n})('Todd');<\/pre>\n<p>O pulo-do-gato aqui \u00e9 isso (que j\u00e1 foi atribu\u00eddo a uma vari\u00e1vel no exemplo anterior):<\/p>\n<\/div>\n<div class=\"wp_syntax\">\n<pre class=\"lang:js decode:true\">(function () {\n})();<\/pre>\n<\/div>\n<p>O par de par\u00eanteses extra \u00e9 necess\u00e1rio. Isso n\u00e3o funciona:<\/p>\n<div class=\"wp_syntax\">\n<pre class=\"lang:js decode:true\">function () {\n}();<\/pre>\n<p>Embora existam v\u00e1rios truques que podem ser feitos para \u201cenganar\u201d o JavaScript e faz\u00ea-lo funcionar. Este, por exemplo, for\u00e7a o parser de JavaScript a tratar o c\u00f3digo que segue <code>!<\/code> como uma express\u00e3o:<\/p>\n<\/div>\n<div class=\"wp_syntax\">\n<pre class=\"lang:js decode:true\">!function () {\n}();<\/pre>\n<p>E existem variantes:<\/p>\n<\/div>\n<div class=\"wp_syntax\">\n<pre class=\"lang:js decode:true\">+function () {\n}();\n\u00a0\n-function () {\n}();\n\u00a0\n~function () {\n}();<\/pre>\n<\/div>\n<p>Mas n\u00e3o \u00e9 preciso se for\u00e7ar a decorar isso para usar a todo momento para fazer uma IIFE.<\/p>\n<p>&nbsp;<\/p>\n<h2>Argumentos da IIFE<\/h2>\n<p>Agora que foi explicado como isso funciona, passemos para os argumento da IIFE:<\/p>\n<div class=\"wp_syntax\">\n<pre class=\"lang:js decode:true\">(function (window) {\n})(window);<\/pre>\n<p>Como isso funciona? Lembre-se, <code>(window);<\/code> \u00e9 onde a fun\u00e7\u00e3o \u00e9 chamada, e onde \u00e9 passado o Objeto <code>window<\/code>. Ent\u00e3o ele \u00e9 passado para a fun\u00e7\u00e3o \u2013 que tamb\u00e9m foi chamada de <code>window<\/code>.<\/p>\n<\/div>\n<p>Ent\u00e3o, o que mais \u00e9 poss\u00edvel fazer? Passar tudo o que for necess\u00e1rio! Por exemplo, passar o Objeto <code>document<\/code>:<\/p>\n<div class=\"wp_syntax\">\n<pre class=\"lang:js decode:true\">(function (window, document) {\n    \/\/ \u00e9 poss\u00edvel usar \"window\" e \"document\" normalmente\n})(window, document);<\/pre>\n<\/div>\n<p>A resolu\u00e7\u00e3o de vari\u00e1veis \u200b\u200blocais \u00e9 mais r\u00e1pida que a de vari\u00e1veis \u200b\u200bglobais, mas esta est\u00e1 numa escala enorme e dificilmente algu\u00e9m vai perceber o aumento da velocidade \u2013 mas vale a pena considerar se h\u00e1 muitas refer\u00eancias a globais!<\/p>\n<p>&nbsp;<\/p>\n<h2>E sobre o <code>undefined<\/code>?<\/h2>\n<p>Em ECMAScript 3, <code>undefined<\/code> \u00e9 mut\u00e1vel. Isso significa que o valor poderia ser transferido com, por exemplo, <code>undefined = true;<\/code>\u2026! Felizmente, no ECMAScript 5 em modo estrito (<code>'use strict';<\/code>) o parser lan\u00e7a um erro quando se depara com isso. Antes disso, come\u00e7ou-se a proteger uma IIFE da maneira j\u00e1 vista:<\/p>\n<div class=\"wp_syntax\">\n<pre class=\"lang:js decode:true\">(function (window, document) {\n    \/\/ \u00e9 poss\u00edvel usar \"window\" e \"document\" normalmente\n})(window, document);<\/pre>\n<pre class=\"lang:js decode:true\">(function (window, document, undefined) {\n})(window, document);<\/pre>\n<p>O que significa que se algu\u00e9m fizesse isso estaria tudo bem:<\/p>\n<\/div>\n<div class=\"wp_syntax\">\n<pre class=\"lang:js decode:true\">undefined = true;\n(function (window, document, undefined) {\n    \/\/ \"undefined\" \u00e9 uma vari\u00e1vel local undefined\n})(window, document);<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<h2>Minificando<\/h2>\n<p>Ao minificar as vari\u00e1veis \u200b\u200blocais \u00e9 que a grandiosidade do padr\u00e3o IIFE realmente pode ser vista. Nomes de vari\u00e1veis \u200b\u200blocais n\u00e3o s\u00e3o realmente necess\u00e1rios se estas foram passadas dessa maneira\u200b\u200b, ent\u00e3o, \u00e9 poss\u00edvel dar o nome que quiser para elas.<\/p>\n<p>Por exemplo, mudar disso:<\/p>\n<div class=\"wp_syntax\">\n<pre class=\"lang:js decode:true\">(function (window, document, undefined) {\n    console.log(window); \/\/ Object window\n})(window, document);<\/pre>\n<\/div>\n<p>Pra isso:<\/p>\n<div class=\"wp_syntax\">\n<pre class=\"lang:js decode:true\">(function (a, b, c) {\n    console.log(a); \/\/ Object window\n})(window, document);<\/pre>\n<\/div>\n<p>Imagine todas as refer\u00eancias a bibliotecas e <code>window<\/code> e <code>document<\/code> minificadas. Claro que voc\u00ea n\u00e3o precisa parar por a\u00ed; \u00e9 poss\u00edvel passar jQuery, tamb\u00e9m, ou qualquer outra coisa que esteja dispon\u00edvel dentro no escopo l\u00e9xico:<\/p>\n<div class=\"wp_syntax\">\n<pre class=\"lang:js decode:true\">(function ($, window, document, undefined) {\n    \/\/ use $ para se referir \u00e0 jQuery\n    \/\/ $(document).addClass('test');\n})(jQuery, window, document);\n\u00a0\n(function (a, b, c, d) {\n    \/\/ Se torna\n    \/\/ a(c).addClass('test');\n})(jQuery, window, document);<\/pre>\n<\/div>\n<p>Isso tamb\u00e9m significa que voc\u00ea n\u00e3o precisa chamar <code>jQuery.noConflict();<\/code> ou qualquer coisa como <code>$<\/code> \u00e9 atribu\u00eddo localmente ao m\u00f3dulo. Aprender como escopos e vari\u00e1veis \u200b\u200bglobais\/locais funcionam ajuda ainda mais.<\/p>\n<p>Passar o c\u00f3digo por um bom minificador certamente garantir\u00e1 a renomea\u00e7\u00e3o de <code>undefined<\/code> para <code>c<\/code> (por exemplo, e apenas se for usado). \u00c9 importante atentar para o fato de que o nome <code>undefined<\/code> \u00e9 irrelevante; s\u00f3 \u00e9 preciso saber que o Objeto referenciado \u00e9 indefinido (undefined) e, como <code>undefined<\/code> n\u00e3o tem qualquer significado especial \u2013 <code>undefined<\/code> \u00e9 o valor que o JavaScript d\u00e1 \u00e0s coisas que s\u00e3o declaradas mas n\u00e3o t\u00eam nenhum valor (nem em IIFE).<\/p>\n<p>&nbsp;<\/p>\n<h2>Ambientes globais n\u00e3o-navegador<\/h2>\n<p>Devido a algumas tecnologias, Node.js, o navegador n\u00e3o \u00e9 sempre o Objeto global, o que pode ser realmente problem\u00e1tico se voc\u00ea est\u00e1 tentando criar uma IIFE para funcionar em m\u00faltiplos ambientes. Por esta raz\u00e3o, h\u00e1 determinadas \u201calternativas\u201d, como isso:<\/p>\n<div class=\"wp_syntax\">\n<pre class=\"lang:js decode:true \">(function (root) {\n})(this);<\/pre>\n<\/div>\n<p>Em um navegador, o ambiente global <code>this<\/code> se refere ao Objeto <code>window<\/code>, de modo que n\u00e3o \u00e9 preciso passar em <code>window<\/code>, \u00e9 sempre poss\u00edvel reduzir para <code>this<\/code>.<\/p>\n<p>Alguns preferem o nome <code>root<\/code>, j\u00e1 que ele pode se referir tanto a ambientes n\u00e3o-navegador, quanto \u00e0 raiz do browser.<\/p>\n<p>Se voc\u00ea estiver interessado em uma solu\u00e7\u00e3o universal (muito \u00fatil para ser usada para a cria\u00e7\u00e3o de m\u00f3dulos em projetos de c\u00f3digo aberto) \u00e9 o <strong>UMD<\/strong> (<em>Universal Module Definition<\/em>):<\/p>\n<div class=\"wp_syntax\">\n<pre class=\"lang:js decode:true\">(function (root, factory) {\n    if (typeof define === 'function' &amp;&amp; define.amd) {\n        define(factory);\n    } else if (typeof exports === 'object') {\n        module.exports = factory;\n    } else {\n        root.MYMODULE = factory();\n    }\n})(this, function () {\n    \/\/ \n});<\/pre>\n<\/div>\n<p>A fun\u00e7\u00e3o est\u00e1 sendo invocado com outra fun\u00e7\u00e3o sendo passada para ela. \u00c9 poss\u00edvel, ent\u00e3o, atribu\u00ed-la ao ambiente relevante \u201cde dentro\u201d. No navegador, <code>root.MYMODULE = factory();<\/code> \u00e9 o m\u00f3dulo IIFE; em qualquer outro ambiente (como Node.js), ser\u00e1 usado <code>module.exports<\/code> ou requireJS se <code>define === 'function' &amp;&amp; define.amd<\/code> resolver como <code>true<\/code>.<\/p>\n<p>&nbsp;<\/p>\n<h2>Conclus\u00e3o<\/h2>\n<p>Como foi visto, usar <strong>IIFE<\/strong> (Express\u00e3o de Fun\u00e7\u00e3o Imediatamente Invocada ou <em>Immediately-Invoked Function Expression<\/em>) \u00e9 extramente ben\u00e9fico. Al\u00e9m de ajudar na performance, por permitir que n\u00e3o seja preciso lookups no c\u00f3digo a procura de vari\u00e1veis globais, permite que seu c\u00f3digo possa ficar \u201cisolado\u201d, protegendo o escopo de uma por\u00e7\u00e3o de c\u00f3digo ou m\u00f3dulo do ambiente em que foi colocado.<\/p>\n<p>O fato de diversos frameworks e bibliotecas JavaScript de renome como jQuery, Backbone.js, Modernizr e outros usarem IIFE j\u00e1 \u00e9 bastante significativo. Use c\u00f3digo de qualidade para fazer c\u00f3digo de qualidade. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nessa postagem, repassamos nosso conhecimento sobre JavaScript IIFE. Descubra o que \u00e9 e por que \u00e9 uma boa pr\u00e1tica us\u00e1-la sempre que puder.<\/p>\n","protected":false},"author":1,"featured_media":3701,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,15],"tags":[180,340,361],"class_list":["post-3697","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dicas","category-javascript","tag-destaque","tag-iife","tag-javascript-2"],"_links":{"self":[{"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/posts\/3697","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/comments?post=3697"}],"version-history":[{"count":0,"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/posts\/3697\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/media\/3701"}],"wp:attachment":[{"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/media?parent=3697"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/categories?post=3697"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/tags?post=3697"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}