As declarações de variáveis são processadas antes de qualquer código ser executado. Isso significa que a declaração da variável é movida para o inicio da função ou do cógido global, isso é conhecido como hoisting. É sempre recomendado declara as variáveis e função no topo antes da inicialização.
Se executarmos o código abaixo no console do navegador irá retornar ò erro ReferenceError pois a variável ainda não foi declarada.
No entanto o código abaixo quando executado irá retornar undefined, pois a declaração (sem a atribuição do valor) é movido para o topo.
No caso de funções é um pouco diferente, neste caso abaixo a função e seu conteúdo são movidos para o topo:
No exemplo 5 o valor retornado é 2 conforme explicação no exemplo 6.
Representação do que acontece com o código do Exemplo 5.
No Exemplo 7 o resultado é outro devido a função ser atribuida a uma variável e o “hoisting” ocorre somente com a declaração não atribuição/inicialização de valor.
Representação do que acontece com o código do Exemplo 7.
Closure
Um closure é uma função interior que tem acesso a variáveis de uma função exterior - cadeias de escopo. O closure tem três cadeias de escopo: ele tem acesso ao seu próprio escopo (variáveis definidas entre suas chaves), tem acesso as variáveis da função exterior e tem acesso as variáveis globais. São usados frequentemente no JavaScript.
Aqui temos outro exemplo interessante, pois a função makeAdder irá construir outras funções que podem adicionar um determinado valor especifico a seu argumento.
Utilização prática do closure,
Exemplo utilizando o jQuery.
Variável Global
A linguagem JavaScript possui dois escopos: global e local. Uma variável declarada fora de uma definição de função é uma variável global, e seu valor será acessível e modificável em todo o seu programa. Todas as variáveis declaradas fora de uma função estão no escopo global. No navegador o contexto global ou escopo é o objeto window (ou o documento HTML inteiro), conforme exemplo abaixo:
Variável por parâmetro
Toda função possui dois parâmetros implícitos this, representando o contexto da função, e arguments, representando os argumentos passados para a função.Quando passamos um parametro para uma função, são atribuídos a eles variáveis de mesmo nome dentro da função, o mesmo ocorre quando passamos variáveis globais por parâmetro. Ao invés de serem inicializados com undefined, são inicializados diretamente pelo arguments.
Instanciação usando uma IIFE
Ben Alman publicou um artigo chamado Immediately-Invoked Function Expression (IIFE). Onde o código abaixo representa um IIFE, uma função definida e auto-executável.
A utilização mais comum é quando queremos cria um escopo no JavaScript para que as variáveis definidas dentro da função não poluam o escopo global (definidas no window).
Representação de como passar uma variável por parâmetro para a IIFE.
Para retornarmos um valor de uma IIFE podemos utilizar o return.
Considerações
Pode-se notar que mesmo não declarando as varíáveis ou função no topo antes da execução as mesmas são movidas assim não retornando erros, no entanto é sempre importante manter as declarações no topo do escopo. E também que o closure permite organizar, otimizar e reaproveitar funções e objetos criados. As diferenças de variáveis locais e globais e como passa-las por parâmetros de uma função. Como também a utilização do IIFE e seu funcionamento.