JavaScript Scope and Hoisting


What is Scope?

Scope determines where variables are accessible in your code. In JavaScript, you’ll mainly deal with:

  • Global Scope
  • Function (Local) Scope
  • Block Scope (added in ES6)

Global Scope

Variables declared outside of any function or block are global.

let name = "Alice";

function greet() {
  console.log("Hello, " + name); // can access global variable
}

Global variables can be accessed from anywhere in the code.

Function Scope

Variables declared inside a function are only available inside that function.

function sayHello() {
  let message = "Hi!";
  console.log(message);
}
                                
sayHello();
// console.log(message); ❌ Error: message is not defined

Block Scope (let and const)

Variables declared with let or const inside {} are only available within that block.

if (true) {
  let age = 25;
  const city = "Delhi";
  console.log(age, city); // ✅ Works here
}
                                
console.log(age); // ❌ Error
console.log(city); // ❌ Error

But var is not block-scoped:

if (true) {
  var test = "Visible outside block";
}
console.log(test); // ✅ Works, but not recommended

Hoisting in JavaScript

Hoisting is JavaScript's default behavior of moving declarations to the top of their scope before code is executed.

Variable Hoisting

Variables declared with var are hoisted, but not their values.

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

Behind the scenes:

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

⚠️ let and const are hoisted but not initialized, so accessing them before declaration throws an error.

console.log(b); // ❌ ReferenceError
let b = 20;

Function Hoisting

Function declarations are hoisted — you can use them before defining:

greet(); // ✅ Works

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

But function expressions (assigned to variables) are not fully hoisted:

sayHi(); // ❌ TypeError: sayHi is not a function

var sayHi = function () {
  console.log("Hi!");
};
Keyword Scope Type Hoisted Re-assignable Block Scoped
var Function/global Yes Yes ❌ No
let Block Yes ❗(TDZ) Yes ✅ Yes
const Block Yes ❗(TDZ) ❌ No ✅ Yes

TDZ (Temporal Dead Zone): The phase between entering scope and variable declaration where it can't be used.

🧪 Practice Exercise:

Task:

  1. Declare a variable inside a function and try accessing it outside.
  2. Try accessing a let variable before it’s declared — observe the error.
  3. Use var in an if block and see if it leaks outside.
  4. Write a function that is called before it's declared using a function declaration.
  5. Compare the behavior of function declaration and function expression with hoisting.