<http://schema.org/articleBody>
"&lt;h2&gt;Um pouco de Teoria antes da divers\u00E3o.&lt;/h2&gt;\r\nMuitas vezes, um simples princ\u00EDpio n\u00E3o compreendido, pode confundir novatos ou especialistas em JavaScript. Neste artigo, vamos tentar entender melhor um problema comum, que \u00E9 mais simples do que parece.\r\n\r\n&lt;h2&gt;Declara\u00E7\u00F5es na frente&lt;/h2&gt;\r\nAntigamente em linguagens como C, se usavam fun\u00E7\u00F5es ou procedimentos para dividir um programa, mas havia um problema: as declara\u00E7\u00F5es deveriam ficar sempre na frente.\r\n\r\nSuponha que voc\u00EA queira usar uma fun\u00E7\u00E3o que junta palavras:\r\n\r\n&lt;pre class=\"lang-javascript\"&gt;juntarPalavras('Arco', '\u00EDris');&lt;/pre&gt;\r\n\r\nMas temos um problema aqui, n\u00E3o? Essa fun\u00E7\u00E3o n\u00E3o foi definida antes de ser chamada! \r\nO programa retornar\u00E1 um erro, pois &lt;strong&gt;juntarPalavras()&lt;/strong&gt; n\u00E3o foi criada, ou acha que a linguagem deve permitir que voc\u00EA use fun\u00E7\u00F5es que s\u00E3o definidas no final do c\u00F3digo?\r\n\r\nDeclarar fun\u00E7\u00F5es no in\u00EDcio do programa resolveu o problema por um tempo, pois todas as fun\u00E7\u00F5es e vari\u00E1veis eram declaradas antes de serem usadas, sendo assim n\u00E3o se tinha erros de refer\u00EAncia.\r\n\r\nCom o tempo os programadores pensaram: \"Mas por que cargas d'\u00E1gua n\u00E3o fazemos isso mais amig\u00E1vel e f\u00E1cil de ler?\", \"por que ler o c\u00F3digo de baixo para cima e, n\u00E3o de cima para baixo?\". Agora podemos colocar as defini\u00E7\u00F5es em qualquer lugar do c\u00F3digo e us\u00E1-los, mesmo antes de realmente serem definidos, que maravilha n\u00E3o?\r\n\r\nO que acontece agora \u00E9 que os compiladores ou at\u00E9 mesmo linguagens runtime leem todo o programa para saber que fun\u00E7\u00F5es e vari\u00E1veis voc\u00EA declarou no c\u00F3digo. Ap\u00F3s isso, a execu\u00E7\u00E3o real acontece e ele j\u00E1 sabe onde est\u00E1 cada coisa. JavaScript faz exatamente isso, o que chamamos de Hoisting.\r\n\r\n&lt;h2&gt;Hora da divers\u00E3o&lt;/h2&gt;\r\nVamos come\u00E7ar com algo leve, para ir aquecendo os neur\u00F4nios, veja o seguinte c\u00F3digo:\r\n\r\n&lt;pre class=\"lang-javascript\"&gt;nome = 'Jonatan';\r\nconsole.log(nome);\r\n// Jonatan\r\n&lt;/pre&gt;\r\n\r\nAt\u00E9 aqui nada de novo, apenas iniciamos a vari\u00E1vel nome com o valor jonatan e mostramos na tela;\r\n\r\nCerto, e que tal tentarmos isso:\r\n\r\n&lt;pre class=\"lang-javascript\"&gt;var nome = meunome;\r\nconsole.log(nome);\r\n// ReferenceError: meunome is not defined\r\n&lt;/pre&gt;\r\n\r\nRecebemos um erro bem obvio n\u00E3o acha? Como vamos definir o &lt;strong&gt;nome&lt;/strong&gt; com o valor de &lt;strong&gt;meunome&lt;/strong&gt; se essa vari\u00E1vel nem existe ainda?\r\n\r\nAgora, deste jeito:\r\n&lt;pre class=\"lang-javascript\"&gt;var nome = meunome;\r\nconsole.log(nome);\r\nvar meunome;\r\n// undefined\r\n&lt;/pre&gt;\r\n\r\nOpa! \u201Cundefined\u201D, sacam a jogada?\r\n\r\nIsso acontece porque o JavaScript n\u00E3o obriga voc\u00EA a declarar vari\u00E1veis, \u200B\u200Bpermite que voc\u00EA defina as fun\u00E7\u00F5es em qualquer lugar que voc\u00EA queira, o que lhe permite usar uma fun\u00E7\u00E3o antes de sua defini\u00E7\u00E3o. O nome hoisting, eleva\u00E7\u00E3o ou at\u00E9 mesmo i\u00E7amento, \u00E9 s\u00F3 um termo especificado, pois ele arranca as declara\u00E7\u00F5es at\u00E9 o topo do seu escopo.\r\n\r\nBeleza, agora qual a diferen\u00E7a entre declara\u00E7\u00E3o e inicializa\u00E7\u00E3o? Simples:\r\n\r\nAqui apenas declaramos a vari\u00E1vel &lt;strong&gt;meunome&lt;/strong&gt;.\r\n\r\n&lt;pre class=\"lang-javascript\"&gt;var meunome;\r\n//undefined\r\n&lt;/pre&gt;\r\n\r\nJ\u00E1 nesta parte iniciamos seu conte\u00FAdo como &lt;strong&gt;Jonatan&lt;/strong&gt;.\r\n&lt;pre class=\"lang-javascript\"&gt;meunome = 'Jonatan';\r\n//Jonatan\r\n&lt;/pre&gt;\r\n\r\nEste \u00E9 o mesmo procedimento feito com as fun\u00E7\u00F5es:\r\n\r\n&lt;pre class=\"lang-javascript\"&gt;console.log(multiplicaNumero(10,10));\r\nvar multiplicaNumero = function(a,b) {\r\n  return a*b;\r\n}\r\n//TypeError: undefined is not a function\r\n&lt;/pre&gt;\r\n\r\nViram? Ele elevou a declara\u00E7\u00E3o var multiplicaNumero, mas como chamamos antes de ele ser iniciado recebemos um erro.\r\n\r\nSe mudarmos para:\r\n&lt;pre class=\"lang-javascript\"&gt;console.log(multiplicaNumero(10,10));\r\nmultiplicaNumero = function(a,b) {\r\n  return a*b;\r\n}\r\n//ReferenceError: multiplicaNumero is not defined\r\n&lt;/pre&gt;\r\nRecebemos o erro nos dizendo que &lt;strong&gt;multiplicaNumero&lt;/strong&gt; n\u00E3o foi declarado.\r\n\r\nAlteramos novamente:\r\n&lt;pre class=\"lang-javascript\"&gt;console.log(multiplicaNumero(10,10));\r\nfunction multiplicaNumero (a,b) {\r\n  return a*b;\r\n}\r\n// 100\r\n&lt;/pre&gt;\r\nE agora o c\u00F3digo executou sem erro porque toda declara\u00E7\u00E3o de fun\u00E7\u00E3o n\u00E3o an\u00F4nima \u00E9 elevada para o topo do escopo.\r\n\r\nF\u00E1cil n\u00E3o \u00E9? Com isso aprendemos que \u00E9 uma boa pr\u00E1tica declarar e/ou iniciar vari\u00E1veis e fun\u00E7\u00F5es no in\u00EDcio do escopo:\r\n\r\n&lt;pre class=\"lang-javascript\"&gt;var a, foo = 'bar';\r\nvar bar = function(){\r\n  var foo = 'foo';\r\n  console.log('local: '+foo);\r\n};\r\nbar();\r\nconsole.log('global: '+foo);\r\n//local: foo\r\n//global: bar \r\n&lt;/pre&gt;\r\n\r\nBoas pr\u00E1ticas nos levam a caminhos melhores. "^^<http://www.w3.org/2001/XMLSchema#string>
<http://tableless.com.br/elevacao-ou-javascript-hoisting/>