⚙️ JavaScript Engine, Execution & Scope
Estimated reading: 4 minutes 363 views

JavaScript — Scope & Hoisting: Complete Guide with Examples


Introduction – Why Scope & Hoisting Matter in JavaScript

Have you ever encountered a ReferenceError in JavaScript and wondered why a variable was undefined even though it seemed declared? Understanding Scope and Hoisting is crucial for writing bug-free, maintainable code.

By the end of this guide, you’ll learn:

  • How JavaScript handles variable visibility via scope
  • What hoisting means and how it impacts variable/function behavior
  • Differences between var, let, and const regarding scope and hoisting
  • Common mistakes and how to avoid them

Let’s dive deep into the core concepts.


What is Scope in JavaScript?

Scope determines the accessibility or visibility of variables.

Types of Scope in JavaScript:

Scope TypeDescription
Global ScopeVariables declared outside any function/block — accessible from anywhere.
Function ScopeVariables declared inside a function — accessible only within that function.
Block ScopeVariables inside {} using let or const — accessible only inside that block.

Example: Function Scope vs Block Scope

function testScope() {
  var x = 10;
  if (true) {
    var x = 20; // same variable!
    console.log("Inside if:", x);
  }
  console.log("Outside if:", x);
}
testScope();

Explanation:

  • var is function-scoped, not block-scoped.
  • The x declared inside if replaces the one outside because both live in the same function scope.

Output:

Inside if: 20
Outside if: 20

Using let and const in Block Scope

function testLet() {
  let x = 10;
  if (true) {
    let x = 20; // new block-scoped variable
    console.log("Inside if:", x);
  }
  console.log("Outside if:", x);
}
testLet();

Explanation:

  • let creates a new block-scoped variable.
  • Inner x is different from the outer x.

Output:

Inside if: 20
Outside if: 10

🎩 What is Hoisting in JavaScript?

Hoisting is JavaScript’s default behavior of moving declarations to the top of the current scope during compile phase.

But there’s a twist:

  • Variables declared with var are hoisted but initialized as undefined.
  • let and const are hoisted but stay in the Temporal Dead Zone (TDZ).
  • Function declarations are fully hoisted.

Example: var Hoisting

console.log(a); // undefined
var a = 5;

Explanation:

  • var a is hoisted to the top.
  • So the engine interprets it as: var a; console.log(a); // undefined a = 5;

Output:

undefined

Example: let/const Hoisting and TDZ

console.log(b); // ReferenceError
let b = 10;

Explanation:

  • b is hoisted, but stays in the TDZ.
  • Accessing b before declaration causes a ReferenceError.

Output:

ReferenceError: Cannot access 'b' before initialization

Function Hoisting

greet(); //  Works fine

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

Explanation:

  • Function declarations are hoisted with their definitions.
  • You can safely call the function before its declaration.

Output:

Hello!

Function Expression is NOT Hoisted

greet(); //  TypeError

var greet = function () {
  console.log("Hi");
};

Explanation:

  • greet is hoisted as undefined (because it’s a var).
  • You can’t invoke undefined.

Output:

TypeError: greet is not a function

Tips & Best Practices

Prefer let and const over var to avoid hoisting confusion.

Always declare variables at the top of their scope to make hoisting clearer.

Use block-scoped variables (let, const) to reduce side effects and improve maintainability.

Avoid using the same variable name inside nested scopes—it increases cognitive load.


Summary – Key Takeaways

Concept What You Should Know
ScopeControls variable accessibility — global, function, and block levels.
HoistingMoves declarations to top of scope during compile — may cause bugs.
var vs let/constvar hoists and lacks block scope. let/const are safer and scoped.
Function hoistingWorks only with function declarations, not expressions or arrow functions.

FAQs — JavaScript Scope & Hoisting

What is the difference between block and function scope in JavaScript?
Answer: Function scope limits access to variables inside a function. Block scope (from let and const) limits access within {} like if, for, etc.

Why does var behave differently than let or const?
Answer: var is function-scoped and hoisted with undefined. let and const are block-scoped and hoisted but stay in the temporal dead zone (TDZ) until initialized.

Can I use a function before it’s defined in the code?
Answer: Yes, if it’s a function declaration. Function expressions and arrow functions can’t be used before they’re defined.

What is the Temporal Dead Zone (TDZ)?
Answer: It’s the time between entering a block and the actual declaration of let/const variables where accessing them causes an error.

Are classes hoisted in JavaScript?
Answer: No, JavaScript classes are not hoisted like functions. Using them before declaration throws a ReferenceError.


Share Now :
Share

JavaScript — Scope & Hoisting

Or Copy Link

CONTENTS
Scroll to Top