Deividy Metheler Zachetti
Basicamente, toda definição em JavaScript é "hoisted" no topo de
seu escopo. O que quer dizer que quando usamos um
var foo = "bar" o compilador JavaScript
vai mover o var foo; no topo da função e
a definição do foo = "bar" ira ficar
onde foi definida.
Considere o seguinte código:
fnExpression(); // => throw TypError!
var fnExpression = function() {
return "Im a expression assigned to a variable";
}
fnExpression(); // => "Im a expression assigned to a variable"
fnStatement(); // => "Im a statement with name"
fuction fnStatement() {
return "Im a statement with name";
}
fnStatement(); // => "Im a statement with name"
var scope = "global";
function fn() {
return scope;
var scope = "local";
}
fn(); // => undefined
Importante ressaltarmos também que uma expressão é
diferente de um statement, basicamente, no exemplo acima,
uma expressão é uma declaração com var fnExpression = function () {...},
enquanto um statement é fuction fnStatement() { ... }).
Expressōes são "hoisted" no topo de seu escopo, mas não a sua inicialização,
logo no exemplo de var fnExpression = function () {...},
a var fnExpression vai para o topo do escopo mas não
a sua inicialização, daí quando tentamos usar a função tomamos um
TypeError, por outro lado, statements são
hoisted por inteiro e por isso o uso da fnStatement()
funciona antes de sua definição.
Para ter uma visualização melhor, é assim que esse código fica do ponto de vista do compilador:
var fnExpression, scope;
function fnStatement() {
return "Im a statement with name";
}
function fn() {
var scope;
return scope;
scope = "local";
}
fnExpression();
fnExpression = function() {
return "Im a expression assigned to a variable";
}
fnExpression();
fnStatement();
fnStatement();
scope = "global";
fn();