JavaScript – Hoisting

Quando começamos a trabalhar, estudar, brincar ou qualquer outra relação com uma linguagem de programação é imprescindível sabermos como funciona alguns pontos, um desses pontos na minha opinião é a sua compilação/interpretação. Ao entender o que acontece nos bastidores das linguagens que usamos para desenvolver nossos programas evitamos bug’s e/ou conseguimos resolve-los de forma mais rápida. Nesse post explicarei um ponto do javaScript chamado Hoisting.

javascript_logo

HOISTING      

  Hoisting ou elevação é o nome dado a um comportamento no javaScript que faz com que todas as declarações, de variáveis ou de funções, sejam movidas para o inicio do escopo atual em tempo de execução. Veja o Exemplo 1:

//Exemplo 1
function conhecendoHoisting(){

  return x;

    function x(){

      return 5;

    }

}

var y = conhecendoHoisting();

y();

No Exemplo 1, em um primeiro momento, poderíamos imaginar que a função conhecendoHoisting() retornaria undefined ocasionando um erro. Porém, não é isso que acontece. Antes de explicar, veja na Figura 1 o retorno da execução do Exemplo 1 utilizando o console do Google Chrome 39.0.2171.71:

Figura 1 - Retorno do exemplo anterior.

Figura 1 – Retorno do exemplo 1 usando o console do Chrome.

Ao encontrar a função conhecendoHoisting() o compilador eleva para o topo do escopo tudo o que é declaração. E tudo o que é execução irá para o final do escopo de acordo com a ordem em que foi escrito. A ordem do escopo, de cima para baixo, fica assim:

  1. Declarações de variáveis;
  2. Declarações de funções; e
  3. Execuções.

Sabendo disso, pode-se dizer que o Exemplo 1 foi compilado da seguinte maneira:

function conhecendoHoisting(){

  function x(){

    return 5;

  }

 return x;

}

var y = conhecendoHoisting();

y();

Vejamos um outro exemplo:


//Exemplo 2
function segundoExemplo(){

  function testeHoisting(){

    return 1;

  }

return testeHoisting;

  function testeHoisting(){

    return 2;

  }

}

var y = segundoExemplo();

y();

Veja na Figura 2 o retorno da execução do Exemplo 2:

Figura 2 - Retorno da execução do exemplo 2 no console do Chrome.

Figura 2 – Retorno da execução do exemplo 2 usando o console do Chrome.

O que acontece no Exemplo 2 em partes é a mesma coisa que acontece no Exemplo 1. As declarações, nesse caso temos as duas funções, vão para o topo do escopo. A diferença aqui é que existem duas funções com o mesmo nome, como o compilador sabe qual deverá retornar? Nesse exemplo as duas funções não podem existir da forma que foram declaradas, não ocorrerá nenhum erro, mas quando o compilador encontrar a segunda declaração ele sobrescreverá a primeira. Sabendo disso, pode-se dizer que o código do Exemplo 2 foi compilado da seguinte maneira:


//Exemplo 2
function segundoExemplo(){
  //esta função será sobrescrita
  function testeHoisting(){

    return 1;

  }

 //esta função sobrescreverá a função anterior que possui a mesma declaração
  function testeHoisting(){

    return 2;

  }

return testeHoisting;

}

var y = segundoExemplo();

y();

Para mostrar o ultimo exemplo entraremos em um novo tópico.

INICIALIZAÇÕES NÃO SÃO ELEVADAS

Anteriormente, nesse mesmo post, comentei que somente as declarações são elevadas. Portanto, uma inicialização não será elevada. Para entender isso, veja os snippet’s 1 e 2:


//Snippet 1
function exemploInicializacao(){

  function testeInicializao(){
   //...
  }
  //Inicialização
  var x = 1;
}

//Snippet 2
function exemploInicializacao(){

  function testeInicializao(){
   //...
  }
  var x;
  x = 1;
}

O Snippet 1 não sofrerá alteração em sua compilação. Já o Snippet 2, será compilado da seguinte maneira:


//Snippet 2
function exemploInicializacao(){
  var x;
  function testeInicializao(){
   //...
  }

  x = 1;
}

Entendendo isso, vamos ver o que acontece com as function expression. Veja o Exemplo 3:


//Exemplo 3
function terceiroExemplo(){

  return x;

  var x = function(){

    return 1;

  }  

}

var y = terceiroExemplo();

y();

O Exemplo 3 tem certa semelhança com o Exemplo 1. Entretanto, nesse caso estamos usando uma function expression. Como vimos anteriormente, somente declarações são elevadas, sendo assim, na execução do Exemplo 3 teremos um erro. Antes de ver como será compilado, veja sua execução:

Figura 3 - Retorno da execução do Exemplo 3 usando o console do Chrome.

Figura 3 – Retorno da execução do Exemplo 3 usando o console do Chrome.

Agora veja como será compilado:


//Exemplo 3
function terceiroExemplo(){

var x;

return x;

x = function(){

  return 1;

}  

}

var y = terceiroExemplo();

y();

Analisando o Exemplo 3, podemos verificar que a atribuição da function para a variável x será ignorada, uma vez que a função terceiroExemplo() será finalizada na linha return x; e desse modo a variável x terá o valor de undefined no momento do retorno.

Bom, espero ter conseguido ser claro nos meus exemplos sobre Hoisting.

Até o próximo post!.

Referencias

http://www.w3schools.com/js/js_hoisting.asp

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function

Anúncios

4 comentários sobre “JavaScript – Hoisting

  1. Caramba, javascript é tenso hein! Eu que só tenho experiência com o mundo desktop, fico abismado ao ver algumas coisas do javascript.. Conseguir declarar duas funções com o mesmo nome no mesmo escopo sem receber nenhum erro é de matar qualquer um do coração..

    Mas, enfim, muito doido seu artigo.. Realmente, como você disse, só conseguimos programar de modo efetivo com uma linguagem ao entender como ela funciona nos bastidores..

    Abraço!
    André Lima

    • Fala André, tudo bom?
      Obrigado pelo feedback. JavaScript é sensacional, todos os dias descobrindo coisas novas. Sempre procuro ir atrás de saber como “as engrenagens” funcionam heheh

      Abraços.
      Wennder Santos

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

w

Conectando a %s