Understanding JavaScript: Scope, Closure, and Hoisting Explained Simply

Rahul SahRahul Sah
2 min read
  1. Scope

Scope determines the accessibility or visibility of variables and functions in different parts of the code during runtime. In JavaScript, scope can be broadly categorized into:

  • Global Scope: Variables declared outside any function or block are accessible everywhere.

  • Function Scope: Variables declared inside a function are only accessible within that function.

  • Block Scope: Variables declared with let or const inside {} blocks are only accessible inside that block.

let globalVar = "I am global";

function myFunction() {
  let functionVar = "I am local to function";
  if (true) {
    let blockVar = "I am local to block";
    console.log(blockVar); // Accessible here
  }
  // console.log(blockVar); // Error: blockVar is not defined here
  console.log(functionVar); // Accessible here
}

console.log(globalVar); // Accessible anywhere
myFunction();

Explanation:

  • globalVar is accessible everywhere.

  • functionVar is accessible only inside myFunction.

  • blockVar is accessible only inside the if block.

  1. Closure

A Closure is a feature where an inner function has access to variables from an outer (enclosing) function’s scope even after the outer function has returned. It “closes over” the variables, preserving their state.

function outer() {
  let count = 0;

  function inner() {
    count++;
    console.log(count);
  }

  return inner;
}

const increment = outer();
increment(); // Output: 1
increment(); // Output: 2
increment(); // Output: 3

Explanation:

  • The inner function inner retains access to the count variable even after outer has finished executing.

  • Each call to increment() remembers and updates the count variable, demonstrating closure.

  1. Hoisting

Hoisting is JavaScript’s default behavior of moving declarations of variables and functions to the top of their containing scope during the compilation phase before code execution. Only declarations are hoisted, not initializations.

console.log(name); // Output: undefined (not ReferenceError)
var name = "Rahul";

greet(); // Output: Hello!

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

Explanation:

  • The variable name is hoisted, but its value is not. So before assignment, it’s undefined.

  • The function greet is fully hoisted, so it can be called before its declaration.

  • If let or const were used instead of var, accessing the variable before declaration would cause a ReferenceError.

1
Subscribe to my newsletter

Read articles from Rahul Sah directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Rahul Sah
Rahul Sah