JavaScript: JavaScript Scope

Last updated: 2026-10-13

Scope determines where a variable can be accessed. Think of it like an ID card — your city ID only works within your province, and your provincial ID won't help you abroad. Variables work the same way: once you leave their scope, they're unreachable.

Related Statements:const let var for

1. Types of Scope and Their Rules

(1) Global Scope

Variables declared with var, let, or const at the outermost level have global scope and can be accessed from anywhere.

HTML
<script>
var globalVar = "I'm a global variable";
function test() {
  console.log(globalVar); // Accessible
}
test();
</script>

Global variables are convenient but can easily pollute the namespace — as projects grow, naming conflicts become inevitable. Minimize global variable usage.

(2) Function Scope

Variables declared with var follow function scope: they only exist within the current function and disappear outside it.

HTML
<script>
function greet() {
  var message = "Hello";
  console.log(message); // Works fine
}
greet();
try {
  console.log(message); // ReferenceError!
} catch(e) {
  console.log("Access failed: " + e.message);
}
</script>

A classic gotcha with var's function scope: using var in a for loop means the variable "leaks" out after the loop ends.

(3) Block Scope

Variables declared with let and const follow block scope: they only exist within the current {}.

HTML
<script>
if (true) {
  let x = 10;
  const y = 20;
  var z = 30;
  console.log("Inside block: x=" + x + ", y=" + y + ", z=" + z);
}
console.log("Outside block: z=" + z); // var isn't restricted by blocks
try {
  console.log(x); // x is not accessible here
} catch(e) {
  console.log("x not accessible: " + e.message);
}
</script>

This is why loop counters should use let instead of var.

(4) Scope Chain

Inner scopes can access variables from outer scopes — like how you can use things from home at school (if you brought them). When looking up a variable, JavaScript searches from the current scope outward, layer by layer, until it reaches the global scope. This chain is called the scope chain.

HTML
<script>
const city = "Beijing";
function outer() {
  const district = "Haidian";
  function inner() {
    const street = "Zhongguancun";
    console.log(street, district, city); // All accessible
  }
  inner();
}
outer();
</script>

Outer scopes cannot access inner scope variables — just like you can't reach into a student's pocket from outside the classroom.

(5) Hoisting

var declarations are "hoisted" to the top of their scope, but assignments are not:

HTML
<script>
console.log(a); // undefined (not an error!)
var a = 5;
// Actual execution order: var a; → console.log(a); → a = 5;
</script>

let and const are also hoisted, but accessing them before declaration throws an error — this region is called the Temporal Dead Zone (TDZ):

HTML
<script>
try {
  console.log(b); // ReferenceError!
} catch(e) {
  console.log("Temporal dead zone: " + e.message);
}
let b = 5;
</script>

Bottom line: always use let and const; avoid the hoisting pitfalls of var.

(6) Closures Explained Intuitively

A closure = a function + the variable environment where it was born. It's like someone who left their hometown but still remembers what it looked like — even if the hometown changed later, their memory of it stays the same.

HTML
<script>
function createCounter() {
  let count = 0;        // This variable is "locked" inside the closure
  return function() {
    count++;
    return count;
  };
}

const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3
// The count variable wasn't destroyed because the returned function still "remembers" it
</script>

createCounter has already finished executing — logically, count should be destroyed. But the returned function holds tightly onto count, so it survives. That's a closure.

(7) Practical Closure Use Cases


▶ Example: var vs let in Loops

▶ Try it Yourself

▶ Example: Scope Chain Demo

▶ Try it Yourself

▶ Example: Closure Counter with Private Variables

▶ Try it Yourself

▶ Example: Hoisting Comparison

▶ Try it Yourself

Related Statements:const let var for

❓ FAQ

Q Why does using var in a for loop cause all callbacks to output the same value?
A Because var has function scope — after the loop ends, there's only one i, and all callbacks share it (which by then equals the loop's final value). With let, each iteration gets its own independent copy of i.
Q Do closures cause memory leaks?
A Closures themselves aren't memory leaks — they intentionally maintain references to variables. A real leak happens when you no longer need a closure, but it's still held by another reference chain, preventing the variable from being garbage collected. The fix: set the reference to null.
Q Should I use let or const?
A Default to const; only use let when you need to reassign. This habit prevents you from accidentally modifying variables that shouldn't change.

📖 Summary

📝 Exercises

  1. Write a function makeGreeter(greeting) that returns a function which, when called with a name, returns greeting + ", " + name. Create two greeting functions with different greetings and verify they don't interfere with each other.
  2. Write a createWallet(initialBalance) function that returns three methods: deposit, withdraw, and getBalance. The balance should not be directly accessible from outside (private variable) — it can only be manipulated through these methods.
  3. Explain the output of the following code and why:
HTML
<script>
for (var i = 0; i < 3; i++) {
  setTimeout(function() { console.log(i); }, 100);
}
</script>

Then modify it to output 0, 1, 2.

Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏