var x = 1;
let y = 1;
if (true) {
var x = 2;
let y = 2;
}
console.log(x);
// Expected output: 2
console.log(y);
// Expected output: 1
js
{
StatementList
}
StatementListStatements and declarations grouped within the block statement.
The block statement is often called the compound statement in other languages. It allows you to use multiple statements where JavaScript expects only one statement. Combining statements into blocks is a common practice in JavaScript, especially when used in association with control flow statements like if...else and for. The opposite behavior is possible using an empty statement, where you provide no statement, although one is required.
In addition, combined with block-scoped declarations like let, const, and class, blocks can prevent temporary variables from polluting the global namespace, just like IIFEs do.
Variables declared with var or created by function declarations in non-strict mode do not have block scope. Variables introduced within a block are scoped to the containing function or script, and the effects of setting them persist beyond the block itself. For example:
js
var x = 1;
{
var x = 2;
}
console.log(x); // 2
This logs 2 because the var x statement within the block is in the same scope as the var x statement before the block.
In non-strict code, function declarations inside blocks behave strangely. Do not use them.
By contrast, identifiers declared with let, const, and class do have block scope:
js
let x = 1;
{
let x = 2;
}
console.log(x); // 1
The x = 2 is limited in scope to the block in which it was defined.
The same is true of const:
js
const c = 1;
{
const c = 2;
}
console.log(c); // 1; does not throw SyntaxError
Note that the block-scoped const c = 2 does not throw a SyntaxError: Identifier 'c' has already been declared because it can be declared uniquely within the block.
In strict mode, function declarations inside blocks are scoped to that block and are hoisted to the top of the block.
js
"use strict";
{
foo(); // Logs "foo"
function foo() {
console.log("foo");
}
}
foo(); // ReferenceError: foo is not defined
A for loop accepts a single statement as its body.
js
for (let i = 0; i < 10; i++) console.log(i);
If you want to use more than one statement in the loop body, you can group them into one block statement:
js
for (let i = 0; i < 10; i++) {
console.log(i);
console.log(i ** 2);
}
let and const declarations are scoped to the containing block. This allows you to hide data from the global scope without wrapping it in a function.
js
let sector;
{
// These variables are scoped to this block and are not
// accessible after the block
const angle = Math.PI / 3;
const radius = 10;
sector = {
radius,
angle,
area: (angle / 2) * radius ** 2,
perimeter: 2 * radius + angle * radius,
};
}
console.log(sector);
// {
// radius: 10,
// angle: 1.0471975511965976,
// area: 52.35987755982988,
// perimeter: 30.471975511965976
// }
console.log(typeof radius); // "undefined"
using declarations in a blockYou can declare variables with using or await using in a block, which causes the object stored in the variable to be disposed when control exits the block. For more information, see resource management.
js
{
using reader1 = stream1.getReader();
using reader2 = stream2.getReader();
// do something with reader1 and reader2
// Before we exit the block, reader1 and reader2 are automatically released
}
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-block |