CPCODELAB
JavaScript

Scope and Hoisting

9 min read

Scope

Scope determines where in your code a variable is accessible. JavaScript has three levels: global scope, function scope, and block scope (let/const only).

javascript
const global = "I am global";

function outer() {
  const outerVar = "outer";

  function inner() {
    const innerVar = "inner";
    console.log(global);   // OK — outer scope
    console.log(outerVar); // OK — lexical scope
    console.log(innerVar); // OK
  }

  inner();
  // console.log(innerVar); // ReferenceError
}

// Block scope
{
  let blockScoped = "only here";
  var notBlockScoped = "leaks out!";
}
// console.log(blockScoped); // ReferenceError
console.log(notBlockScoped); // "leaks out!"

Hoisting

Hoisting is JavaScript's behaviour of moving declarations to the top of their scope before code runs. Function declarations are hoisted fully (you can call them before their definition). var declarations are hoisted but not their values. let and const are hoisted but sit in the Temporal Dead Zone until their line.

javascript
sayHello(); // works! function declarations are fully hoisted

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

console.log(x); // undefined (var hoisted, value not)
var x = 5;

// console.log(y); // ReferenceError (TDZ)
let y = 10;

Relying on hoisting is a code smell. Declare variables before using them and prefer const/let to make intent clear.

Ready to test yourself?
Practice JavaScript— quiz & coding exercises