Compile Ready
Module 2 · Variables & Data Types

The let Declaration

Beginner7m read4m practice11m total
letBlock ScopeTDZLoops

Introduction

let is the modern declaration for values that need to be reassigned. It is block-scoped, cannot be redeclared in the same scope, and has a temporal dead zone before its declaration line is executed.

In interviews, let is usually tested as the fix for var: it prevents accidental block leaks and creates a fresh binding for each for loop iteration.

Why This Matters

Most production JavaScript uses const by default and let when a value changes. Interviewers ask about let to see whether you understand lexical scope and why let loop callbacks print 0, 1, 2 while var callbacks print the final value.

Theory

Block scope

A let binding belongs to the nearest block: { ... }, if, for, while, try, or a function body. It is not visible outside that block.

Featurelet behaviourWhy it matters
ScopeBlock-scopedPrevents values from leaking out of if and loop blocks.
HoistingHoisted but uninitialisedAccess before declaration throws ReferenceError.
RedeclarationNot allowed in the same scopeCatches duplicate-name mistakes early.
ReassignmentAllowedUse when the binding must change.
Loop bindingFresh binding per iteration in for loopsFixes the classic closure bug.

Temporal dead zone

The temporal dead zone (TDZ) is the time from entering a scope until the let declaration is executed. The name exists, but it cannot be read or written yet. That is why typeof x can throw if x is a TDZ binding in the current scope.

Per-iteration bindings

For for (let i = 0; i < 3; i++), the language creates a new lexical binding for each iteration. Closures created inside the loop capture that iteration's i, not a single shared variable.

When to choose let

Use let only when reassignment is part of the design: counters, accumulators, state machines, retry loops, or variables assigned in different branches. If a binding never changes, prefer const.

Visual Diagrams

Block scope and TDZ
enter block
  name exists but is uninitialised  <- TDZ
  reading name throws ReferenceError

  let name = 'Ada'
  name is usable

leave block
  name is out of scope

`let` is known to the scope before its declaration, but it is unusable until initialised.

Code Examples

Block-scoped reassignment

The outer count and inner count are different bindings because the if block creates a lexical scope.

Loading…

No redeclaration in the same scope

Trying to declare the same let name twice in one scope is a SyntaxError, which catches accidental duplicates before runtime.

Loading…

Playground

Loading editor…
Console

Press Run to execute the code and see output here.

Output Prediction

Predict the output #1

javascript
1for (let i = 0; i < 3; i++) {
2 setTimeout(function () {
3 console.log(i);
4 }, 0);
5}

Predict the output #2

javascript
1try {
2 console.log(total);
3 let total = 5;
4} catch (error) {
5 console.log(error.name);
6}

Interview Questions

1How is `let` different from `var`?

let is block-scoped, cannot be redeclared in the same scope, and is unavailable before initialisation because of the TDZ. var is function-scoped, can be redeclared, and is hoisted with undefined. In loops, let creates a fresh binding per iteration, which fixes the classic closure bug.

Asked at:GoogleMicrosoftAmazon

Follow-ups

  • Is `let` hoisted?
  • Why does `typeof` sometimes throw with `let`?

Quiz

1. What happens when you read a `let` variable before its declaration line runs?

Summary

  • `let` is block-scoped and reassignable.
  • A `let` binding is hoisted but cannot be accessed during the temporal dead zone.
  • Redeclaring the same `let` name in one scope is a SyntaxError.
  • `for` loops with `let` create a fresh binding per iteration, fixing the `var` closure bug.

Cheat Sheet

Use for: variables that must be reassigned.

Scope: nearest block.

TDZ: from scope entry until declaration execution; read/write throws ReferenceError.

Loop win: for (let i...) gives each iteration its own i.

Default style: prefer const; use let only when reassignment is needed.