A code block is a group of statements wrapped in curly braces { }. You have been writing them in every if, loop, and function. This lesson looks at blocks directly: what they group, what they hide, and one classic bug they fix.
A block lets several statements act as one unit wherever JavaScript expects a single statement:
if (score >= 90) { // block starts
grade = "A";
console.log("Excellent");
} // block ends
Blocks appear with if / else, for, while, switch, try / catch, functions, and classes.
let message = "outside";
{
let message = "inside"; // a separate variable
console.log(message);
}
console.log(message);
Yes, a pair of braces on their own is legal. A standalone block is occasionally useful to keep temporary variables from leaking into the rest of the code.
The old var keyword only respects function boundaries. It passes straight through if and loop blocks:
if (true) {
var leaked = "I escaped";
let kept = "I stayed";
}
console.log(leaked); // "I escaped"
console.log(kept); // ReferenceError: kept is not defined
With let, every pass through a loop gets its own brand-new copy of the counter. With var, all passes share one. This matters as soon as something runs later, like a timer:
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log("var:", i), 0);
}
for (let j = 0; j < 3; j++) {
setTimeout(() => console.log("let:", j), 0);
}
By the time the var timers run, the loop has finished and the single shared i is 3. Each let timer remembers its own j.
let in for loops fixes it for good.
Everything declared inside a function body (with any keyword) stays inside:
function setup() {
var a = 1;
let b = 2;
const c = 3;
}
setup();
// a, b, and c are all unreachable here
if (ready) {
start();
} // no semicolon needed here
const go = function() {
start();
}; // semicolon: this is an assignment statement that contains a function
JavaScript does not care about indentation, but people do. Indent the contents of every block one level so nesting is visible at a glance:
for (let row = 1; row <= 2; row++) {
for (let col = 1; col <= 2; col++) {
if (row === col) {
console.log(`diagonal ${row},${col}`);
}
}
}
What does this log?
let msg = "A";
{
let msg = "B";
}
console.log(msg);
A. The let msg inside the standalone block is a separate variable that disappears when the block ends.Why do the var timers in the loop all print 3?
i, and by the time the timers run the loop has finished with i at 3var cannot hold numbersvar ignores the loop block, so there is only one i. let creates a fresh copy for every pass, so each timer remembers its own value.Which of these needs a semicolon after its closing brace?
if (ok) { go(); }for (let i = 0; i < 3; i++) { go(); }const run = function() { go(); };function run() { go(); }if, loops, and function declarations do not.let to var and run it againvar / let difference