{"id":3559,"date":"2014-09-17T12:10:48","date_gmt":"2014-09-17T15:10:48","guid":{"rendered":"http:\/\/blog.turbosite.com.br\/?p=3559"},"modified":"2014-09-17T12:10:48","modified_gmt":"2014-09-17T15:10:48","slug":"utilizando-namespacing-em-javascript","status":"publish","type":"post","link":"https:\/\/www.turbosite.com.br\/blog\/utilizando-namespacing-em-javascript\/","title":{"rendered":"Utilizando Namespacing em JavaScript"},"content":{"rendered":"<p>Esta \u00e9 uma postagem encontrada no\u00a0site\u00a0<a title=\"Desenvolvimento para Web\" href=\"http:\/\/desenvolvimentoparaweb.com\/miscelanea\/namespacing-em-javascript\/\">Desenvolvimento para Web<\/a>, achamos interessante e decidimos public\u00e1-la. Para quem desenvolve em Javascript, ser\u00e1 \u00fatil e sem d\u00favida algum novo conhecimento ser\u00e1 adquirido, ent\u00e3o leia o texto completo.\u00a0Este artigo \u00e9 baseado no <span lang=\"en\">post <a href=\"http:\/\/javascriptweblog.wordpress.com\/2010\/12\/07\/namespacing-in-javascript\/\">Namespacing in JavaScript<\/a><\/span> do <span lang=\"en\"><a href=\"http:\/\/javascriptweblog.wordpress.com\/\">JavaScript, JavaScript<\/a>.<\/span><\/p>\n<p>Namespacing em JavaScript pode ser considerado algo um pouco nebuloso no come\u00e7o, mas a organiza\u00e7\u00e3o (e, de certa forma, prote\u00e7\u00e3o) de seu c\u00f3digo \u00e9 algo essencial, que deve ser encarado com muita seriedade e feito com bastante aten\u00e7\u00e3o. JavaScript n\u00e3o possui uma constru\u00e7\u00e3o formal de namespace, ent\u00e3o \u00e9 preciso saber como \u201csimular\u201d namespaces para que se possa desfrutar das vantagens que eles oferecem.<\/p>\n<p>Vari\u00e1veis \u200b\u200bglobais devem ser reservadas a objetos que t\u00eam relev\u00e2ncia para todo o sistema e estas devem ser nomeadas para evitar ambiguidades e minimizar o risco de colis\u00f5es de nomes. Na pr\u00e1tica, isso significa que voc\u00ea deve evitar a cria\u00e7\u00e3o de objetos globais a menos que eles sejam absolutamente necess\u00e1rios. Mas voc\u00ea j\u00e1 sabia disso, certo?!<\/p>\n<blockquote><p>Voc\u00ea deve evitar a cria\u00e7\u00e3o de objetos globais a menos que eles sejam absolutamente necess\u00e1rios.<\/p><\/blockquote>\n<p>Ent\u00e3o, o que voc\u00ea faz sobre isso? A \u201csabedoria popular\u201d mostra que a melhor estrat\u00e9gia de redu\u00e7\u00e3o de risco \u00e9 criar um pequeno n\u00famero de objetos globais que servir\u00e3o como namespaces de facto para m\u00f3dulos subjacentes e subsistemas. A seguir, v\u00e1rias abordagens para namespacing em JavaScript interessantes, que voc\u00ea pode usar em seus projetos imediatamente.<\/p>\n<h2>Namespacing Est\u00e1tico (Static Namespacing)<\/h2>\n<p>O termo \u201cnamespacing est\u00e1tico\u201d est\u00e1 sendo usado como um termo gen\u00e9rico para solu\u00e7\u00f5es em que a denomina\u00e7\u00e3o \u201cnamespace\u201d consta numa codifica\u00e7\u00e3o, propriamente dita. \u00c9 verdade, voc\u00ea pode reatribuir de um namespace para outro, mas o novo namespace vai referenciar os mesmos objetos como se fossem os antigos.<\/p>\n<h3>Atribui\u00e7\u00e3o Direta (Direct Assignment)<\/h3>\n<p>Essa \u00e9 a abordagem mais b\u00e1sica. Exige mais c\u00f3digo, mas \u00e9 segura e inequ\u00edvoca.<\/p>\n<pre class=\"lang:js decode:true \">var myApp = {}\n \nmyApp.id = 0;\n \nmyApp.next = function() {\n    return myApp.id++;  \n}\n \nmyApp.reset = function() {\n    myApp.id = 0;   \n}\n \nwindow.console &amp;&amp; console.log(\n    myApp.next(),\n    myApp.next(),\n    myApp.reset(),\n    myApp.next()\n); \/\/ 0, 1, undefined, 0<\/pre>\n<p>Voc\u00ea poderia tornar a manuten\u00e7\u00e3o futura um pouco mais f\u00e1cil usando <strong>this<\/strong> para fazer refer\u00eancia a propriedades irm\u00e3s, mas isso \u00e9 um pouco arriscado, j\u00e1 que n\u00e3o h\u00e1 nada que impe\u00e7a suas fun\u00e7\u00f5es no namespace de serem reatribu\u00eddas:<\/p>\n<pre class=\"lang:js decode:true\">var myApp = {}\n \nmyApp.id = 0;\n \nmyApp.next = function() {\n    return this.id++;   \n}\n \nmyApp.reset = function() {\n    this.id = 0;    \n}\n \nmyApp.next(); \/\/ 0\nmyApp.next(); \/\/ 1\nvar getNextId = myApp.next;\ngetNextId(); \/\/ NaN whoops!<\/pre>\n<h3>Nota\u00e7\u00e3o de Objeto Literal (Object Literal Notation)<\/h3>\n<p>Nesta abordagem, \u00e9 preciso fazer refer\u00eancia ao nome de namespace apenas uma vez, ent\u00e3o, caso seja preciso alterar o nome mais tarde, isso \u00e9 um pouco mais f\u00e1cil de se conseguir (supondo que voc\u00ea n\u00e3o tenha referenciado o namespace muitas vezes). H\u00e1, ainda, o perigo de que o valor de <strong>this<\/strong> possa ser uma surpresa \u2013 mas \u00e9 um pouco mais seguro assumir que os objetos definidos dentro de uma constru\u00e7\u00e3o de objeto literal n\u00e3o ser\u00e3o reatribu\u00eddos.<\/p>\n<pre class=\"lang:js decode:true\">var myApp = {\n    id: 0,\n \n    next: function() {\n        return this.id++;   \n    },\n \n    reset: function() {\n        this.id = 0;    \n    }\n}\n \nwindow.console &amp;&amp; console.log(\n    myApp.next(),\n    myApp.next(),\n    myApp.reset(),\n    myApp.next()\n) \/\/ 0, 1, undefined, 0<\/pre>\n<h3>Padr\u00e3o de M\u00f3dulo (Module Pattern)<\/h3>\n<p>Hoje em dia \u00e9 bastante comum encontrar por a\u00ed o Padr\u00e3o de M\u00f3dulo (Module Pattern) em c\u00f3digo JavaScript. A l\u00f3gica \u00e9 protegida do escopo global por uma fun\u00e7\u00e3o wrapper (geralmente numa IIFE) que retorna um objeto que representa a interface p\u00fablica do m\u00f3dulo. Por imediatamente invocar a fun\u00e7\u00e3o e atribuir o resultado a uma vari\u00e1vel de namespace, a API do m\u00f3dulo \u00e9 \u201ctrancada\u201d nesse namespace.<\/p>\n<p>Al\u00e9m disso, todas as vari\u00e1veis \u200b\u200bn\u00e3o inclu\u00eddas no valor de retorno permanecer\u00e3o privadas, vis\u00edveis apenas para as fun\u00e7\u00f5es p\u00fablicas que lhes referenciam.<\/p>\n<pre class=\"lang:js decode:true\">var myApp = (function() {\n \n    var id = 0;\n \n    return {\n        next: function() {\n            return id++;    \n        },\n \n        reset: function() {\n            id = 0;     \n        }\n    };  \n})();   \n \nwindow.console &amp;&amp; console.log(\n    myApp.next(),\n    myApp.next(),\n    myApp.reset(),\n    myApp.next()\n) \/\/ 0, 1, undefined, 0<\/pre>\n<h2>Namespacing Din\u00e2mico (Dynamic Namespacing)<\/h2>\n<p>Esta se\u00e7\u00e3o tamb\u00e9m poderia muito bem ser chamada de \u201cinje\u00e7\u00e3o de namespace\u201d (ou namespace injection). O namespace \u00e9 representado por um proxy que \u00e9 referenciado diretamente dentro do wrapper da fun\u00e7\u00e3o \u2013 o que significa que n\u00e3o \u00e9 mais preciso agrupar valores para o return no namespace. Isso faz com que a defini\u00e7\u00e3o de namespace seja mais flex\u00edvel e torna muito f\u00e1cil ter v\u00e1rias inst\u00e2ncias independentes de um m\u00f3dulo existente em namespaces separados (ou at\u00e9 mesmo no contexto global).<\/p>\n<div>Namespacing din\u00e2mico suporta todas as caracter\u00edsticas do Padr\u00e3o de M\u00f3dulo com a vantagem adicional de ser intuitivo e de f\u00e1cil leitura.<\/div>\n<h3>Passando argumento de namespace<\/h3>\n<p>Aqui o namespace \u00e9 simplesmente passado como um argumento de uma <a title=\"JavaScript IIFE como cont\u00eainer de c\u00f3digos\" href=\"http:\/\/desenvolvimentoparaweb.com\/javascript\/javascript-iife-conteiner-de-codigos\/\">Express\u00e3o de Fun\u00e7\u00e3o Imediatamente Invocada<\/a>. A vari\u00e1vel id \u00e9 privada porque n\u00e3o \u00e9 atribu\u00edda ao contexto.<\/p>\n<pre class=\"lang:php decode:true\">var myApp = {};\n(function(context) { \n    var id = 0;\n \n    context.next = function() {\n        return id++;    \n    };\n \n    context.reset = function() {\n        id = 0;     \n    }\n})(myApp);  \n \nwindow.console &amp;&amp; console.log(\n    myApp.next(),\n    myApp.next(),\n    myApp.reset(),\n    myApp.next()\n) \/\/ 0, 1, undefined, 0<\/pre>\n<p>\u00c9 poss\u00edvel at\u00e9 mesmo definir o contexto para o objeto global \u2013 com a mudan\u00e7a de uma palavra! Este \u00e9 um grande trunfo para os fornecedores da bibliotecas (vendors), que podem envolver suas features numa IIFE e permitir que o programador decida se elas devem ser globais ou n\u00e3o (<a href=\"http:\/\/ejohn.org\/\">John Resig<\/a> foi um dos primeiros a adotar esse conceito quando escreveu a jQuery).<\/p>\n<pre class=\"lang:php decode:true\">var myApp = {};\n(function(context) { \n    var id = 0;\n \n    context.next = function() {\n        return id++;    \n    };\n \n    context.reset = function() {\n        id = 0;     \n    }\n})(this);   \n \nwindow.console &amp;&amp; console.log(\n    next(),\n    next(),\n    reset(),\n    next()\n) \/\/ 0, 1, undefined, 0<\/pre>\n<h3>this como proxy de namespace<\/h3>\n<p>O artigo \u201c<a href=\"http:\/\/blogs.sitepoint.com\/2010\/11\/30\/my-favorite-javascript-design-pattern\/\">My Favorite JavaScript Design Pattern<\/a>\u201d aparentemente foi mal compreendido por muitos que pensaram que ele poderia simplesmente recorrer ao Module Pattern. O artigo mostra v\u00e1rias t\u00e9cnicas (o que provavelmente contribuiu para essa confus\u00e3o), mas, em ess\u00eancia, \u00e9 muito interessante e d\u00e1 ensejo ao desenvolvimento de muita coisa boa relacionada a namespacing.<\/p>\n<p>A beleza do padr\u00e3o \u00e9 que ele simplesmente usa a linguagem como foi projetada \u2013 nada mais, nada menos, sem truques, sem firulas. Al\u00e9m disso, j\u00e1 que o namespace \u00e9 injetado atrav\u00e9s da palavra-chave <strong>this<\/strong> (que \u00e9 est\u00e1tica dentro de um determinado contexto de execu\u00e7\u00e3o), ele n\u00e3o pode ser acidentalmente modificado.<\/p>\n<pre class=\"lang:js decode:true\">var myApp = {};\n(function() {\n    var id = 0;\n \n    this.next = function() {\n        return id++;    \n    };\n \n    this.reset = function() {\n        id = 0;     \n    }\n}).apply(myApp);    \n \nwindow.console &amp;&amp; console.log(\n    myApp.next(),\n    myApp.next(),\n    myApp.reset(),\n    myApp.next()\n); \/\/ 0, 1, undefined, 0<\/pre>\n<p>Ainda melhor, a API de apply (e call) prov\u00ea separa\u00e7\u00e3o natural entre contexto e argumentos; ent\u00e3o, fica simples passar argumentos adicionais para o criador do m\u00f3dulo.<\/p>\n<p>O exemplo a seguir demonstra isso e tamb\u00e9m mostra como executar o m\u00f3dulo de forma independente atrav\u00e9s de m\u00faltiplos namespaces:<\/p>\n<pre class=\"lang:php decode:true\">var subsys1 = {}, subsys2 = {};\n \nvar nextIdMod = function(startId) {\n    var id = startId || 0;\n \n    this.next = function() {\n        return id++;    \n    };\n \n    this.reset = function() {\n        id = 0;     \n    }\n};\n \nnextIdMod.call(subsys1);    \nnextIdMod.call(subsys2,1000);   \n \nwindow.console &amp;&amp; console.log(\n    subsys1.next(),\n    subsys1.next(),\n    subsys2.next(),\n    subsys1.reset(),\n    subsys2.next(),\n    subsys1.next()\n) \/\/ 0, 1, 1000, undefined, 1001, 0<\/pre>\n<p>E, se for preciso um gerador global de id:<\/p>\n<pre class=\"lang:js decode:true\">nextIdMod();    \n \nwindow.console &amp;&amp; console.log(\n    next(),\n    next(),\n    reset(),\n    next()\n) \/\/ 0, 1, undefined, 0<\/pre>\n<p>Mas essa ferramenta de gerar de ids mostrada como exemplo n\u00e3o faz jus a todo o potencial desse padr\u00e3o. Envolvendo uma biblioteca inteira e usando a palavra-chave <strong>this<\/strong> como um suporte para o namespace, \u00e9 f\u00e1cil executar a biblioteca em qualquer contexto que se queira (incluindo o contexto global).<\/p>\n<pre class=\"lang:php decode:true\">\/\/ C\u00f3digo de biblioteca\nvar protoQueryMooJo = function() {  \n    \/\/ [...]\n}\n \n\/\/ Seu c\u00f3digo\nvar thirdParty = {};\nprotoQueryMooJo.apply(thirdParty);<\/pre>\n<h2>Considera\u00e7\u00f5es finais sobre Namespacing em JavaScript<\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3562\" src=\"https:\/\/www.turbosite.com.br\/blog\/wp-content\/uploads\/2014\/09\/namespacing-javascript-metafora-turbosite.jpg\" alt=\"namespacing-javascript-metafora-turbosite\" width=\"379\" height=\"317\" srcset=\"https:\/\/www.turbosite.com.br\/blog\/wp-content\/uploads\/2014\/09\/namespacing-javascript-metafora-turbosite.jpg 379w, https:\/\/www.turbosite.com.br\/blog\/wp-content\/uploads\/2014\/09\/namespacing-javascript-metafora-turbosite-300x251.jpg 300w\" sizes=\"auto, (max-width: 379px) 100vw, 379px\" \/><\/p>\n<p>\u00c9 uma pr\u00e1tica comum tentar evitar namespaces aninhados. Eles s\u00e3o mais dif\u00edceis de seguir (para ambos, humanos e computadores) e v\u00e3o encher seu c\u00f3digo de confus\u00e3o desnecess\u00e1ria. <a href=\"http:\/\/michaux.ca\/articles\/javascript-namespacing\">Como Peter Michaux aponta<\/a>, namespaces aninhados podem ser um legado de desenvolvedores Java nost\u00e1lgicos tentando recriar aquelas cadeias longas de pacotes que eles conheciam e amavam\u2026<\/p>\n<p>\u00c9 poss\u00edvel \u201cpropagar\u201d um \u00fanico namespace atrav\u00e9s de diversos arquivos.js (embora apenas por inje\u00e7\u00e3o de namespace ou atribui\u00e7\u00e3o direta de cada vari\u00e1vel), contudo, \u00e9 preciso ter cuidado com as depend\u00eancias. Al\u00e9m disso, \u201cligar\u201d um namespace a um arquivo pode ajudar o leitor a navegar mais facilmente pelo c\u00f3digo.<\/p>\n<p>Uma vez que JavaScript n\u00e3o possui uma constru\u00e7\u00e3o formal de namespace, isso abre margem para v\u00e1rios tipos de solu\u00e7\u00f5es criativas para resolver a quest\u00e3o. Este artigo mostrou apenas algumas delas e, evidentemente, as melhores podem n\u00e3o terem sido abordadas, dada a vasta contribui\u00e7\u00e3o da comunidade a cada dia.<\/p>\n<p>De qualquer forma, estas s\u00e3o algumas das mais conhecidas t\u00e9cnicas para namespacing em JavaScript e, garantimos, estudando um pouco al\u00e9m e sabendo aplicar corretamente em seus projetos, certamente voc\u00ea ter\u00e1 um incremento de qualidade de c\u00f3digo consider\u00e1vel! <\/p>\n","protected":false},"excerpt":{"rendered":"<p>T\u00e9cnica de como Utilizando Namespacing em JavaScript. Como n\u00e3o existe um m\u00e9todo formal, vamos aplicar t\u00e9cnicas interessantes para a constru\u00e7\u00e3o deste recurso.<\/p>\n","protected":false},"author":1,"featured_media":3561,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,6,15,28],"tags":[180,361,435,460,505,506],"class_list":["post-3559","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-desenvolvimento","category-dicas","category-javascript","category-tutoriais","tag-destaque","tag-javascript-2","tag-namespace","tag-objeto","tag-programacao-javascript","tag-programacao-js"],"_links":{"self":[{"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/posts\/3559","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=3559"}],"version-history":[{"count":0,"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/posts\/3559\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/media\/3561"}],"wp:attachment":[{"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/media?parent=3559"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/categories?post=3559"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/tags?post=3559"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}