Block Scoping in JavaScript - GeeksforGeeks

Block Scoping in JavaScript

Last Updated : 7 Oct, 2026

Block scoping restricts the accessibility of variables to the block in which they are declared. Before ES2015, JavaScript primarily used var, which has function scope. ES2015 introduced let and const, which provide block scope.

  • let and const are limited to their enclosing block.
  • var is function-scoped and is not restricted by blocks such as if or for.
  • Block-scoped variables have a Temporal Dead Zone (TDZ) before their declaration is reached.
  • let can be reassigned, while const cannot be reassigned.

Block Scope

A block is a section of code enclosed by curly braces {}. Blocks are commonly created by if, for, while, and standalone {} statements.

Variables declared with let and const are accessible only within their enclosing block.

JavaScript
{
    let p = 110;
    const q = 111;

    console.log(p); 
    console.log(q); 
}

console.log(p); 
console.log(q); 

Here, p and q cannot be accessed outside the block in which they are declared.

Function Scope with var

Variables declared using var have function scope. This means they are accessible throughout the function in which they are declared, even when the declaration appears inside a block.

JavaScript
function printIfGFG(text) {
    if (text === "GeeksforGeeks" || text === "GFG") {
        var message = "Verified Geek";
        console.log(message);
    }

    console.log(message);
}

printIfGFG("GFG");

Although message is declared inside the if block, it can also be accessed later in the function because var does not have block scope.

Variable Hoisting with var

var declarations are hoisted to the top of their function scope. Only the declaration is hoisted, not its assigned value.

JavaScript
function printMessage() {
    console.log(message);
    var message = "Hello";
}

printMessage();

behaves approximately like:

JavaScript
function printMessage() {
    var message;
    console.log(message);
    message = "Hello";
}

printMessage();

This behavior is one reason let and const provide more predictable scoping.

Block Scope with let

The let keyword creates a block-scoped variable.

JavaScript
function printIfGFG(text) {
    if (text === "GeeksforGeeks" || text === "GFG") {
        let message = "Verified Geek";
        console.log(message);
    }

    console.log(message);
}

printIfGFG("GFG");

The first console.log() prints the value, but the second one causes a ReferenceError because message exists only inside the if block.

Reassigning and Redeclaring let

A variable declared with let can be reassigned but cannot be redeclared in the same scope.

JavaScript
let msg = "Try again";

msg = "Try again later";

console.log(msg);

However, redeclaring the variable in the same scope results in a SyntaxError.

JavaScript
let msg = "Try again";
let msg = "Try again later";

Block Scope with const

The const keyword also creates a block-scoped variable. A const variable must be initialized when it is declared and cannot be reassigned later.

JavaScript
const PI = 3.14;
const MAX_USERS = 1000;

console.log(PI);
console.log(MAX_USERS);

A const variable cannot be declared without an initial value.

const pi;

Error:

SyntaxError: Missing initializer in const declaration

It also cannot be reassigned:

const pi = 3.14;

pi = 3.14159;

Error:

TypeError: Assignment to constant variable.

const Does Not Make Objects Immutable

const prevents reassignment of the variable itself. It does not make an object or array immutable.

JavaScript
const user = {
    name: "Ryan"
};

user.name = "Alex";
console.log(user.name);

The object can be modified because the variable still refers to the same object.

Temporal Dead Zone

let and const are hoisted, but they cannot be accessed before their declaration is executed. The period between entering the scope and reaching the declaration is called the Temporal Dead Zone (TDZ).

JavaScript
console.log(message);
let message = "Hello";

Error:

ReferenceError: Cannot access 'message' before initialization

This differs from var, where accessing the variable before its declaration produces undefined.

Block Scope in Loops

Block scoping is particularly useful in loops because each iteration can have its own let binding.

JavaScript
for (let i = 0; i < 3; i++) {
    console.log(i);
}

console.log(i);

The loop prints:

0
1
2

The final console.log(i) produces a ReferenceError because i is scoped to the for loop.

Also Check:

Comment