Elevação de Javascript e declaração de escopo global
Em javascript, a fase de compilação localiza e associa todas as declarações aos seus escopos apropriados.
CASO 1
a = 2;
console.log(a);
Se não for usado no modo estrito, o snippet será considerado realmente processado como:
var a;
a = 2;
console.log(a);
Produto: 2
CASE2
se a declaração acontecer abaixo de console.log ()
console.log(a);
var a = 2;
Aqui na linha 1: o compilador irá verificar a declaração de a em seu escopo, se não for encontrado, o escopo global irá atribuir um e o mesmo código será assumido novamente como
var a;
console.log(a);
a = 2;
Saída: indefinido // já que nenhum valor é atribuído enquanto o interpretador lê o console
CASE3
console.log(a);
a = 2;
Saída: RefErr
Por que isso gera erro de referência e não indefinido?
Respostas
Se você examinar cuidadosamente seus dois primeiros casos, estará sempre declarando a variável ae, em JavaScript, apenas as declarações são levantadas.
Dito isto, na sua Case 3, a variável anunca é declarada, portanto, o içamento não é possível aqui. Com isso, não há nenhuma variável com o nome ano escopo e, portanto ReferenceError,.
Se você olhar a descrição de ReferenceError , verá :
O objeto ReferenceError representa um erro quando uma variável inexistente é referenciada.
Globais implícitos não implicam em uma vardeclaração. Não há içamento deles.