Explicação do que é Hoisting no JavaScript
“Hoisting” significa “içamento”, “levantar”.
Bem, o JavaScript é uma linguagem interpretada e com isso o interpretador realiza muita coisa antes de executar propriamente o código.
Tenha em mente que no JavaScript, variáveis e funções possuem duas importantes etapas: a declaração e a inicialização.
Declaração e inicialização
Veja o trecho abaixo:
var variavelGolbal; // declaração
variavelGlobal = 1; // inicialização
var outraVariavel = 2; // declaração e inicialização em uma única linha
No código acima temos:
- A primeira linha declara uma variável chamada variavelGlobal.
- A segunda linha associa um valor à variável variavelGlobal.
- A terceira realiza as duas etapas de uma vez só na variável outraVariavel.
Tenha em mente que declaração e inicialização de variáveis são duas etapas distintas no JavaScript. Mesmo com a simplicidade em declarar e inicializar a variável em uma única linha, o interpretador realizará os dois passos, identifica a declaração e inicializa a variável.
E o que isso significa em JavaScript?
Na definição do JavaScript, “hoisting” é o processo de mover as definições das variáveis e funções para o topo do escopo onde eslas foram declaradas. O escopo pode ser dentro de uma função, local, ou mesmo global. O escopo é definido onde a variável foi declarada.
Você também deve saber que o JavaScript não possui escopo de blocos.
Para maiores informações: Escopo no Javascript (em inglês).
Logo, o “hoisting” do JavaScript vai, na verdade, mover toda e qualquer declaração de variável ou função para o topo do escopo onde as mesmas foram declaradas.
Vejamos este exemplo:
var variavelGlobal;
variavelGlobal = 1;
var outraGlobal = 2;
function fazAlgo(){
console.log("Dentro da função fazAlgo");
var variavelLocal = 3;
console.log("Variavel local = ", variavelLocal);
}
Quando o interpretador do JavaScript analisa esse código, ele transforma nesse abaixo graças ao “hoisting”:
var variavelGlobal;
var outraGlobal;
variavelGlobal = 1;
outraGlobal = 2;
function fazAlgo(){
var variavelLocal;
console.log("Dentro da função fazAlgo");
variavelLocal = 3;
console.log("Variavel local = ", variavelLocal);
}
Porém fique sabendo que nem tudo são flores, no código abaixo podemos ter uma surpresa:
fazAlgo();
function fazAlgo(){
console.log("Variavel local = ", variavelLocal); // imprime undefined em vez do valor 3
var variavelLocal = 3;
console.log("Variavel local com novo valor = ", variavelLocal); // aqui imprime 3
}
O código acima não possui erro na análise léxica, porém não exibe o valor. Porquê?
O “hoisting” leva a declaração da variável para o início do escopo mas não sua atribuição que permanece no mesmo local que foi definida. Logo, o interpretador entenderia o seguinte código:
fazAlgo();
function fazAlgo(){
var variavelLocal;
console.log("Variavel local = ", variavelLocal); // imprime undefined em vez do valor 3
variavelLocal = 3;
console.log("Variavel local com novo valor = ", variavelLocal); // aqui imprime 3
}
No código abaixo também temos o mesmo problema do código anterior:
var minhaVariavel = "Fellows Devel";
fazAlgo();
function fazAlgo(){
console.log("Minha variável = ", minhaVariavel); // imprime undefined. Nem "Fellows Devel" nem "André Fellows"
var minhaVariavel = "André Fellows";
console.log("Variavel local com novo valor = ", minhaVariavel); // aqui imprime André Fellows
}
Você pode estar se perguntando, “mas como se eu declarei a variável antes de criar a função e outra dentro da função!?”
O motivo é simples, a mesma variável minhaVariavel foi definida dentro da função, e o escopo dela é a função e não o escopo global, pois a declaração de uma variável local tem precedência das globais. Logo, se você utilizar o nome de uma variável global localmente, a que prevalecerá será sempre a local (isto também é conhecido, em JavaScript, como “Shadowing“).
E como o “hoisting” leva apenas a declaração para o início do escopo, a variável não tinha valor quando exibimos ela.
Espero que você tenha aprendido sobre o que é “hoisting” e como ele funciona no JavaScript.
Fontes
www.yourtechchick.com
You Don’t Know JS: Scope & Closures
Se houver alguma dúvida, sugestão ou percebeu algum erro de digitação, não hesite em entrar em contato que responderei tão rápido quanto puder e atribuirei o crédito pela ajuda.
Até mais!
André Fellows