JavaScript let: Syntax, Scope, Hoisting, Examples & Uses

Learn JavaScript let with easy examples. Understand syntax, block scope, reassignment, redeclaration, hoisting, Temporal Dead Zone, let vs var and const, and best practices.

JavaScript let

JavaScript provides several ways to create variables. One of the most commonly used and recommended ways is the let keyword.

The let keyword was introduced in ECMAScript 2015 (ES6). It was designed to provide a safer and more predictable alternative to the older var keyword.

A variable declared with let can be changed later, but it cannot be redeclared in the same scope. It is also block-scoped, which means that it exists only inside the block where it was declared.

For modern JavaScript development, let is especially useful when a variable’s value needs to change during program execution.

What Is let in JavaScript?

let is a JavaScript keyword used to declare a variable.

For example:

let age = 25;

Here:

  • let declares the variable.
  • age is the variable name.
  • 25 is the initial value.

The value of a let variable can be changed later:

let age = 25;

age = 26;

console.log(age);

Output:

26

This ability to change the value is called reassignment.

Basic Syntax of let

The basic syntax is:

let variableName;

You can also declare a variable and assign a value at the same time:

let name = "Rahul";

Multiple variables can be declared separately:

let firstName = "Amit";
let lastName = "Kumar";
let age = 30;

You can also declare multiple variables in one statement:

let x = 10, y = 20, z = 30;

However, declaring variables separately is often easier to read.

Declaring a let Variable Without a Value

A let variable does not have to receive a value immediately.

let score;

console.log(score);

Output:

undefined

Later, you can assign a value:

let score;

score = 95;

console.log(score);

Output:

95

This can be useful when the value is not known when the variable is first declared.

Reassigning a let Variable

One of the main features of let is that its value can be changed.

let city = "Bhubaneswar";

city = "Cuttack";

console.log(city);

Output:

Cuttack

The variable still has the same name, but its stored value has changed.

Another example:

let count = 0;

count = 1;
count = 2;
count = 3;

console.log(count);

Output:

3

This makes let useful for counters, changing states, calculations, loops, and other situations where a value needs to change.

let Cannot Be Redeclared in the Same Scope

A major difference between let and var is that a let variable cannot be redeclared in the same scope.

This is invalid:

let name = "Amit";
let name = "Rahul";

JavaScript will produce a syntax error similar to:

Identifier 'name' has already been declared

However, you can reassign the variable:

let name = "Amit";

name = "Rahul";

console.log(name);

Output:

Rahul

Remember the difference:

  • Reassignment: changing the value of an existing variable.
  • Redeclaration: declaring the same variable again in the same scope.

let allows reassignment but does not allow redeclaration within the same scope.

let Is Block Scoped

The most important feature of let is block scope.

A block is generally created by curly braces {}.

For example:

{
    let message = "Hello";
    console.log(message);
}

The variable is available inside the block.

But it is not available outside the block:

{
    let message = "Hello";
}

console.log(message);

This causes a ReferenceError because message exists only inside the block.

What Is a Block?

A block is a section of code surrounded by curly braces.

Blocks can be found in:

if (condition) {
    // block
}

for (let i = 0; i < 5; i++) {
    // block
}

while (condition) {
    // block
}

They can also be created manually:

{
    // block
}

A variable declared with let belongs to the block in which it was declared.

let Inside an if Statement

Consider this example:

if (true) {
    let message = "Welcome";
    console.log(message);
}

The output is:

Welcome

But this does not work:

if (true) {
    let message = "Welcome";
}

console.log(message);

The variable message is outside its scope.

This behavior helps prevent accidental access to variables that should only be used in a particular section of code.

let Inside a Loop

let is particularly useful in loops.

For example:

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

Output:

0
1
2
3
4

The variable i exists within the loop’s scope.

After the loop finishes, i is no longer accessible:

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

console.log(i);

The final statement causes a ReferenceError.

let and the Loop Closure Problem

The block-scoping behavior of let is especially helpful with asynchronous code.

Consider:

for (let i = 0; i < 3; i++) {
    setTimeout(() => {
        console.log(i);
    }, 1000);
}

The output is:

0
1
2

Each loop iteration gets its own block-scoped i binding.

This is one reason let is generally preferred over var when declaring loop variables.

let and Hoisting

JavaScript declarations are processed before code execution. This behavior is commonly described as hoisting.

let declarations are technically hoisted, but they are not initialized before their declaration is reached.

This creates a special period called the Temporal Dead Zone, commonly abbreviated as TDZ.

For example:

console.log(name);

let name = "Amit";

This does not print undefined.

Instead, it produces a ReferenceError.

The reason is that name is in the Temporal Dead Zone until the declaration is executed.

What Is the Temporal Dead Zone?

The Temporal Dead Zone is the period between entering a variable’s scope and reaching its declaration.

Consider:

{
    // Temporal Dead Zone begins

    console.log(value);

    let value = 100;

    // Temporal Dead Zone ends
}

Accessing value before the let declaration results in a ReferenceError.

After the declaration:

{
    let value = 100;

    console.log(value);
}

The code works normally.

The Temporal Dead Zone helps developers detect accidental use of variables before they have been initialized.

let vs var

The difference between let and var is important in JavaScript.

Scope

var is function-scoped, while let is block-scoped.

Example:

if (true) {
    var x = 10;
}

console.log(x);

This can output:

10

But:

if (true) {
    let x = 10;
}

console.log(x);

causes a ReferenceError.

Redeclaration

var allows redeclaration in the same scope:

var age = 20;
var age = 25;

This is allowed.

let does not allow this:

let age = 20;
let age = 25;

Hoisting

A var declaration can be accessed before its declaration and produces undefined in many cases:

console.log(x);

var x = 10;

Output:

undefined

With let:

console.log(x);

let x = 10;

The result is a ReferenceError because of the Temporal Dead Zone.

let vs const

Both let and const were introduced in ES6 and are block-scoped.

The main difference is whether reassignment is allowed.

With let:

let score = 50;

score = 75;

This is valid.

With const:

const score = 50;

score = 75;

This produces a TypeError.

A simple rule is:

  • Use const when the variable binding should not be reassigned.
  • Use let when the variable needs to be reassigned.
  • Avoid var in modern JavaScript unless there is a specific reason to use it.

Important: const Does Not Make Objects Completely Immutable

Although this article focuses on let, it is useful to understand one common difference between let and const.

This is allowed:

const user = {
    name: "Amit"
};

user.name = "Rahul";

console.log(user.name);

Output:

Rahul

The object can be modified because const prevents reassignment of the variable binding, not all changes inside the referenced object.

By comparison, let allows the variable itself to point to another value:

let user = {
    name: "Amit"
};

user = {
    name: "Rahul"
};

let With Different Data Types

A let variable can hold different JavaScript data types.

String

let name = "Dibya";

Number

let age = 25;

Boolean

let isOnline = true;

Undefined

let result;

Null

let value = null;

Array

let fruits = ["Apple", "Mango", "Banana"];

Object

let person = {
    name: "Dibya",
    age: 25
};

The variable declared with let can later be reassigned to another value.

For example:

let value = 10;

value = "Hello";

console.log(value);

Output:

Hello

JavaScript is dynamically typed, so a let variable is not permanently restricted to one data type.

let With Expressions

You can assign the result of an expression to a let variable.

let a = 10;
let b = 20;

let sum = a + b;

console.log(sum);

Output:

30

Another example:

let price = 500;
let quantity = 3;

let total = price * quantity;

console.log(total);

Output:

1500

Changing a Variable in a Calculation

let is useful when a value needs to be updated repeatedly.

let total = 0;

total = total + 10;
total = total + 20;
total = total + 30;

console.log(total);

Output:

60

The same operation can be shortened using the += operator:

let total = 0;

total += 10;
total += 20;
total += 30;

console.log(total);

Using let With Increment and Decrement

let variables work with increment and decrement operators.

let count = 1;

count++;

console.log(count);

Output:

2

You can also decrement a value:

let count = 5;

count--;

console.log(count);

Output:

4

These operations are common in loops and counters.

Shadowing With let

JavaScript allows a variable inside a nested block to have the same name as a variable in an outer scope.

This is called shadowing.

let message = "Outside";

{
    let message = "Inside";

    console.log(message);
}

console.log(message);

Output:

Inside
Outside

The inner message temporarily hides the outer message inside the nested block.

Although shadowing is legal, excessive use of the same variable names can make code harder to understand.

Shadowing a let Variable With let

This is valid because the variables belong to different nested scopes:

let x = 10;

{
    let x = 20;

    console.log(x);
}

Output:

20

Outside the block:

console.log(x);

Output:

10

Can let Be Used Globally?

Yes. A let declaration can exist at the top level of a JavaScript script or module.

However, there is an important difference between top-level let and properties of the browser’s window object.

For example, in a classic browser script:

let name = "Amit";

console.log(name);

The variable is available in its JavaScript scope, but it does not become a property of window in the same way a top-level var declaration does.

For example:

var x = 10;
let y = 20;

console.log(window.x);
console.log(window.y);

In a classic browser script, window.x can refer to the var variable, while window.y does not refer to the top-level let binding.

This distinction is useful when working with browser-based JavaScript.

let in JavaScript Modules

JavaScript modules have their own module scope.

For example:

let message = "Hello";

export { message };

A variable declared with let inside a module is not automatically placed on the global object.

This helps modules keep their variables organized and prevents unnecessary global variables.

Common Mistake: Accessing let Before Declaration

A common error is trying to use a let variable before declaring it.

Incorrect:

console.log(age);

let age = 25;

Correct:

let age = 25;

console.log(age);

It is good practice to declare variables before using them.

Common Mistake: Redeclaring a let Variable

Incorrect:

let username = "Amit";

let username = "Rahul";

Correct:

let username = "Amit";

username = "Rahul";

If you need a different variable, use a different name:

let firstName = "Amit";
let lastName = "Rahul";

Common Mistake: Expecting Block Variables Outside the Block

Incorrect:

if (true) {
    let message = "Hello";
}

console.log(message);

The variable does not exist outside the if block.

Correct:

let message;

if (true) {
    message = "Hello";
}

console.log(message);

Here, the variable is declared in the outer scope and assigned inside the block.

let in for Loops

A very common pattern is:

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

Here, i is scoped to the loop.

You can also use let to update values while processing an array:

let total = 0;

for (let i = 0; i < 5; i++) {
    total += i;
}

console.log(total);

Output:

10

let With for...of

The let keyword can also be used with for...of.

const fruits = ["Apple", "Mango", "Banana"];

for (let fruit of fruits) {
    console.log(fruit);
}

Output:

Apple
Mango
Banana

If fruit needs to be reassigned within each iteration, let can be appropriate.

let With for...in

You can also use let with for...in.

const person = {
    name: "Amit",
    age: 25
};

for (let key in person) {
    console.log(key);
}

Output:

name
age

Can a let Variable Be Declared Without Initialization?

Yes.

let number;

Its initial value is:

undefined

You can assign a value later:

number = 100;

This is different from trying to access a let variable before its declaration.

For example:

console.log(number);

let number;

This results in a ReferenceError.

Can let Be Declared Multiple Times in Different Blocks?

Yes.

let value = 10;

{
    let value = 20;

    console.log(value);
}

console.log(value);

Output:

20
10

The two variables belong to different scopes.

Best Practices for Using let

Use let carefully and consistently to make JavaScript code easier to maintain.

Use const When Reassignment Is Not Needed

Prefer:

const name = "Amit";

instead of:

let name = "Amit";

if name will never be reassigned.

Use:

let score = 0;

score = 100;

when reassignment is required.

Declare Variables Near Their First Use

Keeping declarations close to where they are needed can improve readability.

Instead of creating many variables at the beginning of a large function, consider declaring them where their purpose becomes clear.

Avoid Unnecessary Shadowing

Although this is valid:

let value = 10;

{
    let value = 20;
}

using different names can sometimes make the code easier to understand.

Give Variables Meaningful Names

Instead of:

let x = 500;

consider:

let productPrice = 500;

Meaningful names make code easier to read and maintain.

Avoid Global Variables When Possible

Variables that are unnecessarily global can cause naming conflicts and make applications harder to maintain.

Use functions, modules, and appropriate block scope to keep variables where they are needed.

Advantages of let

The let keyword provides several important benefits.

1. Block scope

Variables are limited to the block where they are declared.

2. Prevents accidental redeclaration

The same variable cannot be redeclared in the same scope.

3. Supports reassignment

Its value can be changed when required.

4. Better behavior in loops

let provides useful block-scoping behavior for loop variables.

5. Temporal Dead Zone

Accessing a variable before its declaration produces an error rather than silently returning undefined.

6. Modern JavaScript standard

let is part of modern JavaScript and is widely supported by current browsers and JavaScript runtimes.

Disadvantages and Limitations of let

Although let is usually a good choice, it has some characteristics developers should understand.

1. It cannot be redeclared in the same scope

This can cause an error if older code is converted incorrectly.

2. It is block-scoped

A variable declared inside a block cannot be accessed outside that block.

3. It has a Temporal Dead Zone

Using it before its declaration causes a ReferenceError.

These are generally useful safety features rather than serious disadvantages.

let Example for a Shopping Cart

Here is a practical example:

let quantity = 1;
let price = 500;

let total = price * quantity;

console.log(total);

quantity = 2;

total = price * quantity;

console.log(total);

Output:

500
1000

The quantity variable changes, so let is suitable.

let Example for a Counter

A counter is another simple use case:

let counter = 0;

counter++;
counter++;
counter++;

console.log(counter);

Output:

3

let Example With User Status

let status = "Offline";

status = "Online";

console.log(status);

Output:

Online

This kind of pattern is common in interactive applications where a value changes over time.

let Example With Conditional Logic

let message;

if (age >= 18) {
    message = "You are an adult.";
} else {
    message = "You are a minor.";
}

console.log(message);

Here, message is declared outside the conditional block because it needs to be available afterward.

let and Strict Mode

let works normally in JavaScript strict mode.

Strict mode can be enabled with:

"use strict";

Using let also helps avoid some accidental global-variable patterns that were possible with older JavaScript code.

Browser Support

The let keyword is part of ES6, also known as ECMAScript 2015.

Modern browsers and current JavaScript runtimes support it. If you are developing a modern website, web application, Node.js application, or JavaScript module, let is generally safe to use.

Very old browsers may require transpilation if legacy support is necessary.

When Should You Use let?

Use let when:

  • A variable needs to be reassigned.
  • A variable should exist only within a particular block.
  • You are creating a loop variable.
  • A value changes during the execution of a function or program.
  • You want modern JavaScript block-scoping behavior.

For example:

let currentPage = 1;

currentPage++;

console.log(currentPage);

When Should You Not Use let?

Do not use let simply because it is available.

If a variable never needs reassignment, const is usually clearer:

const siteName = "Example";

There is also little reason to use var in new modern JavaScript code unless you specifically need its older function-scoping behavior or are maintaining legacy code.

Quick Comparison

Featureletconstvar
IntroducedES6ES6Older JavaScript
Block scopedYesYesNo
Function scopedYes, within function if declared thereYes, within function if declared thereYes
Can reassignYesNoYes
Can redeclare same scopeNoNoYes
Temporal Dead ZoneYesYesNo
Recommended for modern codeYes, when reassignment is neededYes, by default when possibleUsually no

Frequently Asked Questions About JavaScript let

What is let in JavaScript?

let is a keyword used to declare a block-scoped variable. Its value can be reassigned later, but the variable cannot be redeclared in the same scope.

Is let better than var?

For most modern JavaScript code, let is safer and more predictable because it is block-scoped and does not allow redeclaration in the same scope.

Can a let variable be changed?

Yes. A let variable can be reassigned.

let age = 20;

age = 21;

Can let be redeclared?

No. A let variable cannot be redeclared in the same scope.

let x = 10;
let x = 20;

This causes a syntax error.

Is let block scoped?

Yes. let is block-scoped.

Is let hoisted?

The declaration is hoisted in the JavaScript execution model, but the variable cannot be accessed before its declaration because it remains in the Temporal Dead Zone.

What happens if I access let before declaring it?

JavaScript throws a ReferenceError.

console.log(x);

let x = 10;

What is the difference between let and const?

Both are block-scoped. let allows reassignment, while const does not allow reassignment of the variable binding.

What is the difference between let and var?

let is block-scoped and cannot be redeclared in the same scope. var is function-scoped and allows redeclaration.

Can let store different data types?

Yes. JavaScript variables declared with let can be reassigned to values of different types.

let value = 10;

value = "Hello";

Should I use let or const?

A useful modern rule is to use const by default and use let when the variable must be reassigned.

Final Thoughts

JavaScript let is an important part of modern JavaScript. It provides block scope, allows reassignment, prevents same-scope redeclaration, and works with the Temporal Dead Zone to make variable usage more predictable.

The basic pattern is simple:

let variableName = value;

When the value needs to change:

let score = 50;

score = 75;

When the value should not be reassigned, prefer const:

const maximumScore = 100;

Understanding let is essential for writing clean and reliable JavaScript. Once you understand its scope, reassignment rules, hoisting behavior, and differences from var and const, you will have a much stronger foundation for working with modern JavaScript code.

Scroll to Top