Chapter II · Variables & Values

The let Keyword

Introduced in ES6, let allows you to declare block-scoped variables that can be reassigned later.

01 What is let?

The let keyword declares a variable that is block-scoped and mutable (reassignable). Unlike older mechanisms, let prevents accidental variable leakage outside of loops, conditionals, and code blocks.

Variables declared with let exist in a Temporal Dead Zone (TDZ) from the start of their enclosing block until their declaration statement is evaluated.

02 Simple Example

Using let inside a conditional code block.

let.js
let count = 10;
if (true) {
  let count = 20; // Different variable inside this block
  console.log(count); // 20
}
console.log(count); // 10

The inner let count is isolated to the if block, leaving the outer variable untouched.

03 How It Works

Block scoping ensures that identifiers declared with let are bound strictly to their enclosing curly braces {} rather than the entire function or global scope.

if (true) { let msg = "hi"; console.log(msg); ✓ visible here } msg does not exist outside this block

Block scoping confines let variables to their immediate enclosing code block.

04 Step-by-Step

  1. Execution enters a block containing a let declaration.

  2. The variable enters the Temporal Dead Zone; accessing it throws a ReferenceError.

  3. The declaration statement is evaluated, and the variable is initialized.

  4. The variable can now be read or reassigned within that block.

05 Mental Model

"A sticky note on a desk that only people inside that specific room can read and modify."

It stays contained where it was placed and cannot bleed out into surrounding rooms.

06 Common Mistakes

Assuming let hoists like var. let declarations are technically hoisted (the engine knows about them at the top of the block), but they stay uninitialized inside the Temporal Dead Zone. Reading them before the declaration line throws ReferenceError: Cannot access 'x' before initialization — a much safer failure than var's silent undefined.

Best practice: default to const everywhere, and reach for let only when you know a binding must be reassigned (loop counters, accumulators). This makes reassignment visually obvious wherever it happens.

07 Interview Questions

Q: Can a let variable be redeclared in the same scope?

No — redeclaring a let in the same block throws a SyntaxError, unlike var which allows it silently.

Q: Why was let introduced when var already existed?

To fix var's function-scoping and hoisting quirks — let is block-scoped, which matches how most other languages scope variables and avoids common bugs like loop-variable capture.

Key Takeaway

The let keyword provides block-scoped, reassignable variables while preventing hoisting confusion and scope leakage.

Related Concepts