Function Hoisting in Javascript

Function Hoisting in Javascript

Introduction:

This article is second part of the series covering an important concept Hoisting in Javascript. If you miss my previous article then i would recommend to go through that first here.

In this article, we will go through concept of function hoisting in javascript and with some examples, we will try to find out how it affects output of our code.

What is Function Hoisting?

Function hoisting is a JavaScript mechanism where function declarations are moved to the top of their scope before code execution.

Similar to the variable hoisting, javascript engine also hoist function declarations. It moves the function declarations to the top of code. This means we can call hoisted function before its declaration.

Let's look at an example to understand this:

add(2,3);    

function add(a,b) {  
  console.log(a+b);
}

What will be the output of above code?

  1. Uncaught ReferenceError: add is not defined
  2. 5
  3. undefined

The correct answer is 2nd option i.e. 5.

Explanation:

In above code, we called function add with arguments, before its declaration. The compiler (during creation phase of execution context) move the declaration to the top before executing it. Thus, our code will look like this after compilation:

function add(a,b) {  
  console.log(a+b);
}

add(2,3);

This looks simple! But there is an important point which i will discuss now. Let's take a step back and look at some of the ways in which we can create or define a function.

  1. Function declaration
  2. Function expression
  3. Arrow functions

Function Declaration

Function declaration defines a function using function keyword with specified parameters.

Example of function declaration is same, that we used above:

function add(a,b) {  
  console.log(a+b);
}

Function declarations are hoisted. They can be invoked before their declaration.

We have already explained hoisting of function declaration above with the help of an example. Let's move to the next type of creating function.

Function Expression

A function expression is very similar to function declaration. The main difference is that we have the option to omit the function name in function expression and also store the function expression in a variable, which can be used to invoke that function.

By definition, it seems a bit tricky. But don't worry, let's look at an example to understand this better:

var add = function(a,b) {
   console.log(a+b);
};

add(2,3);

In above code we have created an anonymous function (a function without a name) and stored it in a variable add. Later, we invoked that anonymous function using variable add.

An important point to note here:

Function expressions are not hoisted.

This means if we try to invoke that function expression before its creation, then javascript engine will throw an error.

add(2,3);   //Uncaught TypeError: add is not a function

var add = function(a,b) {
   console.log(a+b);
};

I hope now we understand the difference between function declaration and function expression. There is new type of functions introduced in ES6 named as Arrow function. Let's look at how it behaves.

Arrow Functions

Arrow functions are more compact way of writing function expressions in javascript.

var add = (a,b) => console.log(a+b);
add(2,3);   //Output: 5

As per the definition, arrow functions are a compact way of writing function expressions. Thus, it follows same hoisting rules as that of function expressions.

add(2,3);   //Uncaught TypeError: add is not a function
var add = (a,b) => console.log(a+b);

Summary:

  • Function declarations in javascript are hoisted to top of scope during creation phase of execution context.
  • Function expressions are not hoisted.
  • Arrow functions introduced in ES6, is a compact way of creating function expressions.
  • Arrow functions are not hoisted.

I hope we have a good understanding of function hoisting in javascript now. In the third part of hoisting concept, we will go through some interview questions based on hoisting in javascript. Stay tuned!