JavaScript basics: Hoisting, part two => functions

Tiety Kooistra
19-01-2017

Recap hoisting with variables

In JavaScript basics: Hoisting, part one => variables I discussed JavaScript’s hoisting behavior with variables. Now I will continue with setting out the consequences of hoisting for functions. To get a good start, a small recap. The hoisting definition as stated in part one.

function and variable declarations are hoisted/moved to the top of the scope in JavaScript.

JavaScript functions

So function declarations are important to know about in relation to hoisting. JavaScript has several ways of writing down your functions. Not all of them are treated in the same way when it comes to hoisting. Therefor it is important to recognize the different syntax’s, to be able to know their behavior concerning hoisting. The function declaration and expression are most important in combination with the concept of hoisting. Lets get a code example to see how both syntax’s behave.

// Function declaration
hoisted(); // logs "foo"

function hoisted() {
  console.log("foo");
}

// Function expression
notHoisted(); // TypeError: notHoisted is not a function

var notHoisted = function() {
   console.log("bar");
};

Function declarations are hoisted to the top of the scope. So a function declaration can be called before the function is written down in the code. This means the whole function is hoisted, from the function keyword to the last curly brace. Remember that when JavaScript is executed, it first scans the whole file for declarations and  then moves them to the top of the scope. Function expressions on the other hand are not hoisted completely to the top of the scope. Only its variable declaration is hoisted. The assignment, in this case an anonymous function is done at the point in the code where it is written. That’s why you get the error saying ‘notHoisted’ is not a function, while it is only a declared and initialized variable without any value.

Time for some more challenging examples.

Same names

What will happen if there are 2 functions one an expression and one a declaration with the same name. While they are different things JavaScript wont trow an error but what will happen?

showState();

function showState() {
  console.log("Ready");
} 

var showState = function() {
  console.log("Idle");
};

How would the code look after the hoisting process?

// moved to the top (function declaration)
function showState() {     
  console.log("Ready");
} 

// moved to the top (variable declaration)
var showState;            

showState();  // output: "Ready"

// left in place (variable assignment)
showState = function() {   
  console.log("Idle");
};

Now we can read the code from top to bottom. There is no question anymore about what the output should be, there is only one function to be called and it returns ‘Ready’. What can we conclude about hoisting here? At least that function declarations are hoisted before variable declarations.

Overwriting functions

What if there are 2 functions both function declarations whit the same name? They will overwrite each other right. Is hoisting still a process to recon with in that case?

function getNumber () {
    function chooseNumber() {
        return 12;
    }
    return chooseNumber();
    
    function chooseNumber() {
        return 7;
    }
}

What is returned? Function declarations are moved up tot the top of the scope. Both ‘chooseNumber’ functions will be hoisted and therefor the second one will overwrite the first. When the ‘getNumber’ function is called it will then return ‘7’.

function getNumber () {
    function chooseNumber() {
        return 12;
    }
    function chooseNumber() {
        return 7;
    }

    return chooseNumber();
}

chooseMystery(); // returns 7

Summary

After all this it becomes clear why you should put your variables at the top and why not to call a function before you wrote it. If you abide by this rules hoisting wont bother you. But now that you know how it works you can also take advantage of hoisting. In some design patterns for example you will use function declarations so you can call all your functions at the top of your file. This way it is easier to see what is going on at a glace, while the details are at the end of the file.

Points to remember:

  • All declarations of functions and variables are hoisted/moved to the top of the scope.
  • Hoisting happens before your code is executed.
  • Function declarations are hoisted before variable declarations.