JavaScript Code Blocks

A code block is a section of code enclosed in curly braces {}. Code blocks define scope boundaries for let and const (but not var). Understanding how blocks work with different variable declarations is fundamental to writing bug-free JavaScript.

Block Statements

A block statement groups zero or more statements inside curly braces {}. Blocks are used in if/else, for, while, switch, try/catch, and can also stand alone. With let and const, a block creates a new scope.

Basic Block Statements
// Standalone block — creates scope for let/const
{
  let x = 10;
  const y = 20;
  console.log("Inside block:", x, y);
}

// x and y are NOT accessible here
// console.log(x); // ReferenceError

// Nested blocks
{
  let outer = "outer";
  {
    let inner = "inner";
    console.log(outer);
    console.log(inner);
  }
  console.log(outer);
  // console.log(inner); // ReferenceError
}

Block Scope with let and const

Variables declared with let and const are block-scoped. They only exist within the block where they are declared. This is the expected behavior in most programming languages and prevents accidental variable leakage.

let and const Block Scope
let a = "global a";

if (true) {
  let a = "block a";
  let b = "block b";
  console.log(a);
  console.log(b);
}

console.log(a);
// console.log(b); // ReferenceError

// const works the same way
const PI = 3.14;
if (true) {
  const PI = 3.14159;
  console.log("Inner PI:", PI);
}
console.log("Outer PI:", PI);

var Leaks Out of Blocks

Unlike let and const, var does NOT respect block scope. Variables declared with var are scoped to the nearest function (or global scope). They 'leak' out of if blocks, for loops, and other code blocks.

var Ignores Block Scope
if (true) {
  var leaked = "I leaked out!";
  let contained = "I stayed inside";
}

console.log(leaked);
// console.log(contained); // ReferenceError

// var in a for loop leaks
for (var i = 0; i < 3; i++) {
  // loop body
}
console.log("var i after loop:", i);

// let in a for loop is contained
for (let j = 0; j < 3; j++) {
  // loop body
}
// console.log(j); // ReferenceError

Function Blocks

Function bodies are blocks that create scope for all variable types (var, let, and const). This is the only type of block that constrains var. Each function call creates its own scope.

Function Block Scope
function example() {
  var funcVar = "I'm function-scoped";
  let funcLet = "I'm also function-scoped";
  const funcConst = "Me too!";

  console.log(funcVar);
  console.log(funcLet);
  console.log(funcConst);
}

example();

// None of these are accessible outside
// console.log(funcVar);   // ReferenceError
// console.log(funcLet);   // ReferenceError
// console.log(funcConst); // ReferenceError

// Each call has its own scope
function counter() {
  let count = 0;
  count++;
  console.log(count);
}
counter();
counter();

Loop and Conditional Blocks

Loop blocks (for, while, do...while) and conditional blocks (if, else, switch) create new block scopes for let and const. This is especially important in loops where closures capture variables.

Loop Block Scope (var vs let)
// Classic problem with var in loops
var funcsVar = [];
for (var i = 0; i < 3; i++) {
  funcsVar.push(function() { return i; });
}
// All functions share the same 'i' (which is 3)
console.log(funcsVar[0]());
console.log(funcsVar[1]());
console.log(funcsVar[2]());

// Fixed with let — each iteration gets its own 'i'
let funcsLet = [];
for (let i = 0; i < 3; i++) {
  funcsLet.push(function() { return i; });
}
console.log(funcsLet[0]());
console.log(funcsLet[1]());
console.log(funcsLet[2]());

// Switch block
let val = 2;
switch (val) {
  case 1: {
    let msg = "one";
    console.log(msg);
    break;
  }
  case 2: {
    let msg = "two";
    console.log(msg);
    break;
  }
}
DeclarationBlock ScopeFunction ScopeGlobal Scope
varNo (leaks out)YesYes
letYesYesYes (no window prop)
constYesYesYes (no window prop)
functionVaries by modeYesYes
📝 Note: Always use let and const instead of var. Block scoping with let/const is more predictable and prevents common bugs like variable leakage from loops and conditionals. The var keyword only respects function scope, which leads to confusing behavior in blocks.
Exercise:
What happens to a variable declared with var inside an if block?
Try it YourselfCtrl+Enter to run
Click Run to see the output here.