Simplifying Javascript Techniques: A Guide to the Power of Hoisting

Hoisting is a funky Javascript mechanism where variables and functions get moved around like they're playing a game of musical chairs.

Here's the deal:

  • Only declarations get hoisted. Assignments or other executable logic are left in place, just like your friend who always bails on moving day.
  • Functions get hoisted first and then variables, kind of like how you prioritize pizza over veggies.

For example:

var x = 2;

Javascript sees this as two statements: var x and x = 2. The first statement, var x, is executed during the compilation phase while the second statement, x = 2, is left in place for the execution phase.

Check out this next example:

(function() {
    console.log(x); var x = 2;  // undefined
})();

The execution of the above code goes something like this:

  1. var x; gets hoisted to the top
  2. console.log(x); is executed, but since x hasn't been assigned a value yet, it's undefined
  3. x = 2; assigns the value 2 to x

Now let's try a slightly different example:

(function() {
    x = 2; 
    var x; 
    console.log(x); // 2
})();

The execution of this code goes like this:

  1. var x; gets hoisted to the top
  2. x = 2; assigns the value 2 to x
  3. console.log(x); prints 2 to the console

By the way, if you declare a function like this:

(function(){
    foo();
    function foo(){
        console.log(a);  //undefined
        var a = 2;
    }
})();

The function's declaration gets hoisted to the top, so even though a hasn't been assigned a value yet, you can still call the function without any errors.

But if you declare a function expression like this:

(function(){
    foo();
    var foo = function bar(){
    };
})(); // TypeError

You'll get a TypeError because function expressions don't get hoisted.

However, you can still override previous function declarations with subsequent ones, like this:

(function() {
    foo(); // prints c

    function foo() {
        console.log('a');
    }

    var foo = function() {
        console.log('b');
    };

    function foo() {
        console.log('c');
    }
})();

In this case, the last function declaration overrides the previous ones, so the final output is c.

And that's hoisting in a nutshell! It may seem a little weird, but once you get the hang of it, it's actually quite helpful. If you want to learn more, check out the book You Don't Know JS.