Chapters

FundamentalsChapter 8 of 21

let

A name you can reassign, scoped to the block it lives in.

A name that can change

let declares a variable you intend to reassign. Everything else about it matches const.

JavaScript

JavaScript

let attempts = 0;

attempts = attempts + 1;
attempts += 1;

console.log(attempts);

Output

2

Block scope

A let variable exists only inside the nearest pair of braces. Outside them the name does not exist at all.

JavaScript

JavaScript

let visible = 'outer';

if (true) {
  let hidden = 'inner';
  console.log(visible, hidden);
}

console.log(typeof hidden);

Output

outer inner
undefined

This is why loops behave the way you expect. Each pass of a for loop with let gets its own copy of the counter:

JavaScript

JavaScript

const jobs = [];

for (let i = 0; i < 3; i += 1) {
  jobs.push(() => i);
}

console.log(jobs.map((job) => job()));

Output

[0, 1, 2]

Note

The same loop written with var logs [3, 3, 3], because there is only ever one counter for the whole loop. That difference is the whole reason let exists.

Declaring twice

Redeclaring a name in the same scope is a syntax error, which catches a whole class of accidental collisions.

JavaScript

JavaScript

let total = 1;
let total = 2; // SyntaxError: Identifier 'total' has already been declared

Output

SyntaxError: Identifier 'total' has already been declared

The same name in a nested block is fine, because that is a different scope.

Declaring without a value

A let may be declared empty and filled in later. Until then it holds undefined.

JavaScript

JavaScript

let result;

console.log(result);

result = 'ready';
console.log(result);

Output

undefined
ready

Test yourself

2 questions

Where does a let variable exist?

Show the answer

Inside the nearest braces only Block scope is the difference from var, and it is why loop counters behave predictably.

What happens if you declare the same let name twice in one scope?

Show the answer

A SyntaxError The program refuses to start, which is better than two unrelated values quietly sharing a name.

Next chapter

const

A name that cannot be pointed somewhere else, and what that does not protect.