Fundamentals javascript

Learn once for all how hoisting works in javascript

Spread the love
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

Ten thousand feet view about hoisting

 

If you are a front-end developer probably the first time you’ve heard the word ‘hoisting’ you might have thought “what in the seven hells does this mean???” (or if this is the first time you are seeing this word maybe you are thinking this now).

Hoisting is a fancy word for a simple concept (that if not correctly understood can lead you to hours of code blaming). Hoisting is a term to describe the act of the javascript parser moving declarations(both variables and functions) to the beginning of the current scope. This happens only at the conceptual level, so you will not really see your code being moved around. The JS engine does this behind the scenes.

Let’s understand how it works

 

In javascript when we are dealing with variables we usually do these three things:

  1. Declare the variable.
  2. Initialize it or assign a new value to it.
  3. use the variable value.

Sometimes we even do some of these steps in the same line.

//quick example
var age; // Variable Declaration
age = 25; //Variable Initialization
console.log(age); //Variable Usage
//or in shorthand
var name = 'my name'; //Variable Declaration and Initialization
console.log(name);

 

or when we are dealing with functions we would do something like this:

//quick example
//function declaration
function foo(){
  return 'bar';
}

 

This is such a natural thing that we never stop to think about what happens under the hood. So let’s do it now.

The javascript engine does multiple passes on the source code before actually executing it, one of the very first things that the engine will do is to go through all your code searching for variable and functions declarations. Once it finds these declarations it will move them to the top of the current scope.

let’s see this example:

var foo = "bar";
foo = "other value";
var age = 5;
function() myAmazingFunction(){
    // do stuff
}

 

Under the hood the code it will look like this after the engine pass(remember that this happens only at the logical level)

var foo, age;
function() myAmazingFunction(){
      // do stuff  
};
foo = "bar";
foo = "other value";
age = "5";

 

Practical hoisting implications

 


The first implication of hoisting is that you can use a variable or function before actually declaring it, this comes from the fact that javascript engine will move our declarations to the top of our scope. This explains why codes like this one do not throw errors.

myAmazingFunction();
//do lots of other stuff
function myAmazingFunction(){
  //my magic logic
}

 

Other interesting hoisting implication is this common gotcha

var foo = "outside scope value";
function bar(){
  console.log(foo); //undefined
  var foo = "inside scope value";
  console.log(foo); //inside scope value
}
bar();

 

some beginner programmers may wonder the reason why this line:

console.log(foo);

 

will print undefined. If you don’t know how hoisting works this behavior may look weird. Actually undefined will be printed because under the hood the real executed code looks like this:

var foo;
function bar(){
  var foo; //this declarations shadows the outer one
  console.log(foo); //undefined
  foo = "inside scope value";
  console.log(foo); //inside scope value
}

foo = "outside scope value";
bar();

 

Function declaration x function expression

 

One important thing to note is that hoisting will move only declarations and not assignments. So for example, if you have a function expression and try to invoke it before its assignment, you will get an error

 

myAmazingFunction(); //myAmazingFunction is not a function
var myAmazingFunction = function(){
  //logic here
}

 

Remember this happens because even if we have the declaration of myAmazingFunction being moved to the top, the Initialization of it will happen after we tried to invoke it, this happens because we are not dealing with a function definition, we are dealing with a function expression instead.

Final thoughts

 

For completeness sake, I need to mention that behind the scenes things are actually implemented a little bit different. The ECMAScript standard does not define hoisting as “the declaration gets moved to the top of the function”. Handling code happens in two steps: the first one is parsing and entering the context and the second one is runtime code execution. In the first step variables, function declarations and formal parameters are created. In the second stage function expressions and unqualified identifiers (undeclared variables) are created. However, for practical purposes, we can adopt the concept of hoisting.

I hope you enjoyed the reading, my focus on this article was to demystify some of the strange behaviors you sometimes may experience when dealing with hoisting. Hope you liked it. See you in the next post.