Skip to main content
Piotr Majkutewicz
Back to Blog

Understanding Hoisting in JavaScript

Hoisting is a JavaScript mechanism where variables and function declarations are moved to the top of their respective scopes during the compilation phase, before code execution.

Function Hoisting

Function declarations are hoisted completely, including their body:

javascript
// This works thanks to hoisting
sayHello(); // Outputs: "Hello!"

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

Variable Hoisting

var Declarations

Variables declared with var are hoisted and initialized with undefined:

javascript
console.log(x); // Outputs: undefined
var x = 5;

// The above is interpreted as:
var x;
console.log(x);
x = 5;

let and const Declarations

While technically hoisted, they are not initialized and remain in the "temporal dead zone" until declaration:

javascript
console.log(x); // Throws ReferenceError
let x = 5;

console.log(y); // Throws ReferenceError
const y = 10;

Class Hoisting

Classes, like let and const, are hoisted but remain uninitialized:

javascript
const p = new Person(); // ReferenceError

class Person {
  constructor() {
    this.name = "John";
  }
}

Function Expressions

Function expressions are not hoisted like function declarations:

javascript
sayHello(); // TypeError: sayHello is not a function

var sayHello = function() {
  console.log("Hello!");
};

// With const/let it would be a ReferenceError instead
sayHi(); // ReferenceError

const sayHi = function() {
  console.log("Hi!");
};

Best Practices

  • Always declare variables at the top of their scope
  • Use const and let instead of var to avoid hoisting-related bugs
  • Declare functions before using them
  • Be aware of the temporal dead zone when using let and const
  • Consider using strict mode to catch potential hoisting issues