Como funciona o JavaScript Hoisting
- #JavaScript
Neste tutorial você aprenderá sobre o JavaScript Hoisting e como ele funciona debaixo dos panos.
Introdução ao JavaScript Hoisting
Quando a engine do JavaScript executa o código, ela cria o execution context global, que tem duas fases: criação e execução.
Durante a fase de criação, a engine do JavaScript move as declarações de variável e função para o topo do seu código. Esse recurso é conhecido como Hoisting em JavaScript.
Hoisting de Variáveis
O Hoisting de variáveis significa que a engine do JavaScript move as declarações de variáveis para o início do script. Por exemplo, o exemplo a seguir declara a variável counter e inicializa seu valor como 1:
console.log(contador); // Indefinido
var contador = 1;
Neste exemplo, referenciamos a variável counter antes da declaração.
No entanto, a primeira linha de código não causa um erro. A razão é que a engine do JavaScript move a declaração da variável para o início do script.
Tecnicamente, o código se parece com o seguinte na fase de execução:
contador var;
console.log(contador); // Indefinido
contador = 1;
Durante a fase de criação do execution context global, a engine do JavaScript coloca o contador de variáveis na memória e inicializa seu valor como indefinido.
A palavra-chave let
O seguinte declara a variável counter com a palavra-chave let:
console.log(contador);
let contador = 1;
O JavaScript emite o seguinte erro:
"ReferenceError: Não é possível acessar 'contador' antes da inicialização"
A mensagem de erro explica que a variável 'contador' já está na memória. No entanto, não foi inicializada.
Nos bastidores, a engine do JavaScript eleva as declarações de variáveis que usam a palavra-chave let. No entanto, ele não inicializa as variáveis let.
Observe que se você acessar uma variável que não existe, o JavaScript lançará um erro diferente:
console.log(alien);
let contador = 1;
Aqui está o erro:
"ReferenceError: alien não está definido"
Hoisting de Funções
Assim como as variáveis, a engine do JavaScript também eleva as declarações de função. Isso significa que a engine do JavaScript também move as declarações de função para o início do script.
Por exemplo:
let x = 20,
y = 10;
let resultado = add(x, y);
console.log(resultado);
function add(a,b){
return a + b;
}
Neste exemplo, chamamos a função add() antes de defini-la. O código acima é equivalente ao seguinte:
function add(a, b){
return a + b;
}
let x = 20,
y = 10;
let resultado = add(x,y);
console.log(resultado);
Durante a fase de criação do execution context, a engine do JavaScript coloca a declaração da function add() na memória. Para ser preciso, a engine do JavaScript cria um objeto do tipo Function e uma referência de função chamada add que se refere ao objeto de função.
Function Expression
O exemplo a seguir altera a adição de uma função regular para uma function expression:
let x = 20,
y = 10;
let resultado = add(x,y);
console.log(resultado);
var add = function(x, y) {
retun x + y;
}
Se você executar o código, ocorrerá o seguinte erro:
"TypeError: add não é uma função"
Durante a fase de criação do execution context global, a engine do JavaScript cria a variável add na memória e inicializa seu valor para undefined.
Ao executar o código a seguir, o add é indefinido, portanto, não é uma função:
let resultado = add(x,y);
A variável add é atribuída a uma função anônima somente durante a fase de execução do execution context global.
Arrow Functions
O exemplo a seguir altera a expressão da função add para uma arrow function:
let x = 20,
y = 10;
let resultado = add(x,y);
console.log(resultado);
var add = (x, y) => x + y;
O código também emite o mesmo erro que o exemplo de function expression porque as arrow functions são syntactic sugar para definir function expressions.
"TypeError: add não é uma função"
Semelhante às functions expressions, as arrow functions não fazem hoisting.
Resumo:
- O Hoisting do JavaScript ocorre durante a fase de criação do execution context, que move as declarações de variáveis e funções para o início do script;
- A engine do JavaScript eleva as variáveis declaradas usando a palavra-chave let, mas não as inicializa como as variáveis declaradas com a palavra-chave var;
- A engine do JavaScript não eleva as function expressions nem as arrow functions.
Onde me achar:
- GitHub
E aí, gostaram do artigo? Deixem seus comentários :)