DEV Community

Lukas Gaucas
Lukas Gaucas

Posted on • Edited on

Hoisting – please read this , if you really want to understand its behaviour in JavaScript (2 ed.)

If you'd like an article please give a thumb as your encouragement is my encouragement as well . Thank you !


VARiables

Variables declared upon var and function declaration inclusively , are said to be lifted to the top of the scope as where it had been declared in . The true reality : nothing is lifted up . Hoisting in JavaScript refers to the process whereby the just-in-time (JIT) compiler allocates memory for variables & function declarations prior to execution of the remaining code , thus creating the illusion of “moving” to the top . Worth to mention , rather than function declaration, function expression ARE NOT hoisted !

Example 1

console.log(age); 
var age;
// undefined (no error thrown)
Enter fullscreen mode Exit fullscreen mode

LETs & CONSTs

Variables declared with let and const are hoisted as well , but unlike variables declared with var , let & const are not initialized (a.k.a. assigned) with the value of undefined . Last sentence is quite jeopardizing . Let me fix myself . It appears variables declared upon using keyword let also initializes with value of undefined , but it suffers from so-called temporal-dead-zone (TDZ) [1] .

Example 2

console.log(age); // TDZ
let age = 101;
// ReferenceError : { Cannot access 'age' before initialization
Enter fullscreen mode Exit fullscreen mode

To fix temporal dead zone (TDZ) issue , let's tweak Example 2 as so :

Example 2.1

// TDZ
let age;
console.log(age); // # no more error
// undefined
Enter fullscreen mode Exit fullscreen mode

Variables declared with const follows similar pattern of let except it explicitly MUST go with some initial value , otherwise Missing initializer in const declaration will be thrown .


Differences between the keywords used in global context (window) :

var vs. let
var gglobal = "global" -- let lglobal == "global"
console.log(gglobal) -- console.log(lglobal)
"global" -- undefined

Definition of "declared global(ly)" exploit

Developers, especially newbies, like to play with words stating that if declared with var it's global, you bet ! Technically it depends ! Let's examine the following Example 3 :

Example 3

var mostGlobal = this; // use keyword THIS (lower-cased) to test scope binding
console.log("global (at most): ", mostGlobal === window);

function lexical(){
    console.log("global scope got penetrated into", mostGlobal)
    var innerThis = this; // not available outside function – that's what it means then said that VAR are FUNCTION-SCOPED
    var innerWindow = window; // not available outside function – that's what it means then said that VAR are FUNCTION-SCOPED
    // console.log(private) // # uncomment to reproduce error i.e. ReferenceError: private is not defined
    function closure() {
    console.log("global scope got penetrated into", mostGlobal)
    // function with preserved data is called closure
    // let's add own variable to closure that will be available within closure and deeper nested functions , but not outside the function variable was declared :
    var private;
    console.log(innerThis, innerWindow, innerThis === innerWindow);
    }
closure();
}
lexical();
Enter fullscreen mode Exit fullscreen mode

NOTE : Exactly due to most globally declared variables such as mostGlobal are most dangerous due to brutal penetration through all levels of functions whenever such functions executed .

RULE OF THUMB : avoid declaring variables with var , use either let or const (at best) although the remaining has its own pros & cons (not discussed in this article)


Concluded : variables declared within global scope (window) using keyword var e.g. var globalMost or window.globalMost automatically become global(-scoped) . Conversely, declared so within N-tuple nested function , it becomes function-scoped by nature which bears resemblance (as if) declared globally , although it's not anymore as it's not available outside the function unless within the function where it was declared and the nested inner N-tuples (Example 3) .


Hopefully you got introduced what really Hoisting is about . I can see myself this article lacks explanation in function-scoped (var) AND block-scoped (let & const) . However , this article intended to explain about Hoisting as titled specifically , not Scoping , nevertheless the following two are strongly coupled. Meanwhile article about Scoping or relevant topic will be in process of baking , you can find more about the Scoping reading this article by well known dev Tania Rascia published on Digital Ocean [2]

Thanks for reading and see you in the next one !


References

Top comments (0)