Hoisting - JavaScript
O Hoisting é o processo de acessar variáveis antes de sua definição. Isso pode parecer estranho, mas é uma característica do compilador JavaScript. A compilação do código ocorre em duas passagens. Na primeira passagem, o compilador coleta todas as declarações de variáveis e identificadores, sem executar código ou chamar métodos. Na segunda passagem, ocorre a execução do código. Assim, mesmo que uma variável seja definida após o seu uso, não haverá erro, pois o compilador já conhece todas as variáveis desde a primeira passagem.
É como se o código com a definição de variáveis e funções fosse "erguido" para cima antes de seu uso. Essa "elevação" é conhecida como hoisting.
Variáveis var
As variáveis var
undefined
console.log(foo);
Sua execução resultará em um erro de ReferenceError: foo is not defined
foo
Vamos adicionar a definição da variável:
console.log(foo); // undefined
var foo = "Tom";
Neste caso, o console exibirá o valor undefined
foo
undefined
console.log(foo)
Outro exemplo:
var c = a * b;
var a = 7;
var b = 3;
console.log(c); // NaN
Aqui, ocorre a mesma situação. As variáveis a e b são usadas antes de serem definidas. Por padrão, recebem o valor undefined
undefined
undefined
NaN
O mesmo se aplica a funções. Podemos chamar uma função antes de defini-la:
display();
function display() {
console.log("Hello Hoisting");
}
Neste caso, recebemos um erro de TypeError: display is not a function
display
display
undefined
Variáveis let e const
O hoisting para variáveis let
const
undefined
let
console.log(foo); // Uncaught ReferenceError: Cannot access 'foo' before initialization
let foo = "Tom";
console.log(foo); // Não será executado
Aqui, obtemos um erro de Uncaught ReferenceError: Cannot access 'foo' before initialization
foo
Isso é diferente de uma variável let declarada, mas não inicializada:
let foo; // Por padrão, foo = undefined
console.log(foo); // undefined
foo = "Tom";
console.log(foo); // Tom
Uma variável let
undefined
O mesmo vale para const:
console.log(foo); // Uncaught ReferenceError: Cannot access 'foo' before initialization
const foo = "Tom";
console.log(foo); // Não será executado
Aqui, obtemos um erro de Uncaught ReferenceError: Cannot access 'foo' before initialization
'foo'
Isso mostra a diferença no comportamento de hoisting para variáveis var
let
const