JS Scope
Scope is the region of code where a name is visible. JavaScript has three: global, function, and block.
The three scopes
| Scope | Created by | Visible to |
|---|---|---|
| Global | Top-level declarations. | Everywhere. |
| Function | Each function body. | The function and nested ones. |
| Block | Any { … } — if, for, while, raw braces. | let and const inside it only. |
Block scope in action
JS
function example() {
if (true) {
let block = "x"; // block-scoped — only inside the if
const k = "y"; // same
var fn = "z"; // function-scoped — escapes the block
}
// block ← ReferenceError
// k ← ReferenceError
fn // "z" ← still visible
}
Lexical scope & closures
Inner functions can read names from the enclosing scope — that's what closures are.
JS
function counter() {
let count = 0; // captured by the inner function
return () => ++count;
}
const next = counter();
next(); // 1
next(); // 2
next(); // 3
Shadowing
JS
const name = "outer";
{
const name = "inner"; // shadows the outer one in this block
console.log(name); // "inner"
}
console.log(name); // "outer"
Tip: Avoid polluting the global scope. Wrap top-level scripts in a module (
type="module") or an IIFE — names declared inside don't leak.Example
Example
<!DOCTYPE html>
<html>
<body>
<p id="out"></p>
<script>
document.getElementById("out").textContent = "Hello from JS Scope!";
</script>
</body>
</html>
Try it Yourself »
Exercise
Make a counter that captures the outer state in a closure.
function counter() {
count = 0; return () => ++count; }
Reassignable variable inside the function.
Discussion
Loading…