JavaScript: Function Hoisting

JavaScript: Function Hoisting

On our previous post, we looked at variable hoisting. In this post, we will take a look at function hoisting, which is part two of JavaScript Hoisting concept and part of our JavaScript basic concept series.

Let's start with a code example,

foo(); //Output: Hello world

function foo() {
	console.log("Hello world")';
}
Function declaration hoisted

The above way of writing a method with a function keyword is called a function declaration.

Function declarations are always hoisted by JavaScript in its existing scope. And you can see that the function foo() is available before its declaration.

You can write a function in another way and its called function expression. With function expression, you declare an anonymous function and assign it to a variable. Let's see that with a code example.

foo(); // Reference Error": 'foo' is not a function

var foo = function() {
	console.log("Hello world");
}

or in ES6

let foo = () => {
	console.log("Hello world");
}
Function expression do not get hoisted

Function expression on both ES5 and ES6 will not get hoisted. The variable declaration will get hoisted but without a function assignment. The interpretation of the above code by JavaScript will be,

var foo;
foo(); //Referance Error: 'foo' is not a function
console.log(foo); //Output: undefined

var foo = function() {
	console.log("Hello world");
}
JavaScript interpretation of function expression

ES6 Classes

The data type of an ES6 class is a Function. So, classes behave the same as function when it comes to hoisting. Class declarations are hoisted and Class expressions are not.

There is one extra rule with class declarations, you have to declare a class before you can use it. Let's take a look,

var rectangle = new Rectangle(10, 5, 5); // Reference Error: Cannot access 'Rectangle' before initialisation 
class Rectangle {
	constructor(length, width, height) { 
    	this.length = length;
        this.width = width;
        this.height = height;
    }
    volume() {
    	return this.length * this.width * this.height;
    }
    area() {
    	return this.length * this.width;
    }
}
Class declaration hoisting

The fact that the error is "initialisation" error and that it is not a 'is not defined' error, proves that JavaScript can see its definition hence it is hoisted.

Same as function expression, class expressions are not hoisted.

var rect = new Rectangle(10, 5, 5); // Type Error: Rectangle is not a constructor
var Rectangle = class Rectangle {
	constructor(length, width, height) { 
    	this.length = length;
        this.width = width;
        this.height = height;
    }
    volume() {
    	return this.length * this.width * this.height;
    }
    area() {
    	return this.length * this.width;
    }
}
Class expression do not hoist

Summary

  1. Function and ES6 Class declarations are hoisted.
  2. Function and ES6 Class expressions are not hoisted.
  3. ES6 let and const hoist the same way as var does.
Show Comments