JavaScript

JavaScript Hoisting

  • ligeiro Deividy Metheler Zachetti
  • 2018-02-04
blog-detail-hero

function hoisted () {}

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();