When learning JavaScript, one of the most important concepts to understand is scope. But as the language evolved, new keywords like let
and const
introduced a twist: block scope.
In this post, we’ll break down what scope is, what block scope means, and how to avoid common mistakes when working with variables in JavaScript.
🧠 What is scope?
Scope is the area of your code where a variable is accessible.
There are three main types of scope in JavaScript:
- Global scope — accessible everywhere
- Function scope — accessible only inside a specific function
- Block scope — accessible only inside a specific block (like
{ }
)
Example of global vs function scope:
var name = 'Maria'; // Global
function greet() {
var message = 'Hello ' + name; // Function scoped
console.log(message);
}
greet(); // "Hello Maria"
console.log(name); // "Maria"
console.log(message); // ReferenceError
Here, message
is only accessible inside the greet
function.
🔐 What is block scope?
Block scope was introduced in ES6 with let
and const
. It limits variable visibility to the block where it's defined (for example, inside an if
or for
statement).
{
let a = 10;
const b = 20;
var c = 30;
}
console.log(a); // ReferenceError
console.log(b); // ReferenceError
console.log(c); // 30
a
andb
are block-scoped: not accessible outside the{ }
c
is function-scoped: still accessible becausevar
ignores block scope
🧩 Function scope vs block scope
Let’s look at a comparison:
function test() {
if (true) {
var x = 1;
let y = 2;
const z = 3;
}
console.log(x); // 1
console.log(y); // ReferenceError
console.log(z); // ReferenceError
}
test();
Inside the if
block:
x
(declared withvar
) is hoisted to the function scopey
andz
(withlet
andconst
) stay inside theif
block
This is one of the key differences between var
and the newer keywords.
⚠️ Common pitfall: loops
If you’ve ever written a loop and all your event listeners behave the same, block scope fixes that.
Example with var
:
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1000);
}
// Output: 3 3 3
Now with let
:
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1000);
}
// Output: 0 1 2
let
creates a new i
for each loop iteration—problem solved.
✅ Recap
var
is function-scopedlet
andconst
are block-scoped- Use
let
andconst
for safer, more predictable code - Block scope makes it easier to avoid bugs, especially in loops and conditional blocks
📌 Conclusions
Understanding scope helps you write cleaner and less error-prone JavaScript.
Function scope was the default for years, but block scope with let
and const
is now the recommended way to declare variables.
If a variable only needs to live inside an if
, for
, or other block, use block scope—it keeps things tidy and avoids unexpected behavior.