Joshua Colvin

Understanding JavaScript: Hoisting

Published September 05, 2016

To understand hoisting you must first understand how scope works in JavaScript.

In JavaScript, hoisting occurs when variable or function declarations are moved to the top of a scope. It’s important to make a distinction between declarations and assignments. The code var name = "World"; could be broken up into the following:

  • var name is the the declaration (the part that gets hoisted).
  • name = 'World' is the assignment (which is not hoisted).

To demonstrate let’s create a function that says hello.

function sayHello() {
  console.log('Hello ', name)
}

sayHello() // Uncaught ReferenceError: name is not defined

This function will throw an error since we have not declared the name variable. Let’s declare the variable after we log it to see what happens.

function sayHello() {
  console.log('Hello ', name)
  var name = 'World'
}

sayHello() // Hello undefined

Now we get Hello undefined which means our variable name exists but does not hold a value. This is because our variable declaration, var name has been hoisted to the top of the sayHello functions scope but not the assignment, name = "World". This function is being interpreted like this:

function sayHello() {
  var name
  console.log('Hello ', name)
  name = 'World'
}

sayHello() // Hello undefined

Here’s another example to show how the variable declaration gets hoisted:

function sayHello() {
  name = 'World'
  var name
  console.log('Hello ', name)
}

sayHello() // Hello World

This will log the desired value Hello World since the var name was hoisted to the top of the sayHello function. This function is being interpreted like this:

function sayHello() {
  var name
  name = 'World'
  console.log('Hello ', name)
}

sayHello() // Hello World

Function declarations are also hoisted.

sayHello() // Hello World

function sayHello() {
  var name = 'World'
  console.log('Hello ', name)
}

We can call the function seemingly before it is declared since the declaration is hoisted to the top of the scope (in this case global scope). It is important to note that this only works for function declarations and not function expressions.

sayHello() // Uncaught TypeError: sayHello is not a function

var sayHello = function() {
  var name = 'World'
  console.log('Hello ', name)
}

This throws a TypeError saying sayHello is not a function since sayHello hasn’t been assigned a value when it is called, it has only been declared.

Since hoisting can lead to unexpected behavior it’s a best practice to declare your variables at the top of a function.

Find this article helpful or interesting? Follow me on Twitter for related content.

Joshua Colvin is a UI Software Engineer specializing in building component libraries. He lives with his wife and two kids in Michigan.