JavaScript hoisting behavior

Hoisting is a JavaScript internal behavior where variable, function, and class declarations are saved to the memory during the compile phase, right before your code is executed.

Let’s see a technical example of hoisting in action. Suppose you have the following JavaScript code:

console.log(`The value of num is: ${num}`);
var num = 8;

At first, you may think that JavaScript should throw an error because the code is trying to log the value of num before the variable is declared and initialized. But here’s what you will get when you run the code above:

The value of num is: undefined

Because hoisting puts the variable declaration num into memory before execution, your code will be executed like this by JavaScript:

var num;
console.log(`The value of num is: ${num}`); // undefined
num = 8;

Hoisting will automatically assign undefined as the initial value for all variables declared using the var keyword. If you declare the variable using let or const keyword, JavaScript will still throw an error because the variable is not initialized.

The following code will throw a ReferenceError:

console.log(`The value of num is: ${num}`);
let num = 8; // ReferenceError: num is not defined

This is hoisting in a nutshell. It puts all declarations: variables, functions, and classes into memory before code execution.

Is hoisting good or bad?

JavaScript developers tend to write code in a way that avoids hoisting. This is because hoisting is bad for variables, but it’s actually good for functions and classes.

As you’ve seen in the example above, variables declared with var keyword can easily cause bugs by returning undefined value to the caller instead of returning the value that you initialized. It’s not much of a problem when you declare variables with let or const keyword.

But for functions and classes, you may want to call them before declarations because it will give you a more readable code.

Here’s an example of a function call before declaration:

greetings("Jack", "Charlie");

function greetings(sender, addressee) {
  console.log(`Hello, my name is ${sender}`);
  console.log(`Nice to meet you, ${addressee}!`);
}

Even though it’s subjective, most people would consider the above code is more readable than the following:

function greetings(sender, addressee) {
  console.log(`Hello, my name is ${sender}`);
  console.log(`Nice to meet you, ${addressee}!`);
}

greetings("Jack", "Charlie");

There’s no right or wrong answer when it comes to hoisting because it’s not something you can do about. This is what the JavaScript compiler does. That being said, you should keep in mind two rules about hoisting when you write your code. Here they are:

  • JavaScript only hoists declarations
  • Function and class expressions are not hoisted

By now you should be familiar with the first rule, so let me explain the second.

JavaScript allows you to create a function using function declaration, which looks like the following:

function greetings() {
  console.log("Hello World!");
}

And an alternative syntax called function expression as you can see below:

let greetings = function () {
  console.log("Hello World!");
};

Both are valid functions, but since function expressions are not hoisted, calling on function expression before it has been defined will cause an error:

greetings();

let greetings = function () {
  console.log("Hello World!");
};

Output:

Error: Cannot access 'greetings' before initialization

The same goes for classes:

let tesla = new Car("Tesla Model 3"); 

let Car = class {
  constructor(name) {
    this.name = name;
  }
};

Output:

Error: Cannot access 'Car' before initialization

Still, you don’t need to worry about the second rule because the most common way to write functions and classes is to use declarations instead of expressions. I hope this article has helped you to understand what hoisting does and how it affects the way you can code JavaScript programs.

Take your skills to the next level ⚡️

I'm sending out an occasional email with the latest tutorials on programming, web development, and statistics. Drop your email in the box below and I'll send new stuff straight into your inbox!

No spam. Unsubscribe anytime.