Scope & Hoisting in JavaScript
Understanding scope and hoisting is crucial for writing predictable JavaScript code and avoiding common bugs.
🎯 What is Scope?
Scope determines the accessibility (visibility) of variables, functions, and objects in your code.
Types of Scope:
- Global Scope - Accessible from anywhere
- Function Scope - Accessible within function
- Block Scope - Accessible within block (ES6)
- Module Scope - In ES6 modules
💡 Scope Chain
JavaScript uses lexical scoping: inner functions have access to variables of their outer functions. If a variable is not found in current scope, JavaScript looks up the chain.
Scope Resolution Order:
- Current scope
- Parent scope
- Global scope
- ReferenceError if not found
📚 Scope Examples
Let's see how different scopes work in practice.
Global Scope
Variables declared outside any function. Accessible everywhere.
Function Scope
Variables declared with var inside a function.
Block Scope
Variables declared with let/const inside .
⚡ var vs let vs const
Understanding the differences between var, let, and const is essential for modern JavaScript.
var
- Function scoped
- Hoisted with undefined
- Can be redeclared
- Avoid in modern code
let
- Block scoped
- Hoisted but in TDZ
- Cannot be redeclared
- Use for variables that change
const
- Block scoped
- Hoisted but in TDZ
- Cannot be reassigned
- Use for constants
⬆️ Hoisting
Hoisting is JavaScript's behavior of moving declarations to the top of their scope before code execution.
⚠️ Temporal Dead Zone (TDZ):
Variables declared with let and const are hoisted but cannot be accessed until their declaration is evaluated. This period is called the Temporal Dead Zone.
🔒 Closures
A closure is a function that remembers its outer variables and can access them.
🎯 Closure Use Cases:
- Data Privacy - Create private variables
- Function Factories - Create specialized functions
- Event Handlers - Remember context
- Currying - Transform functions
- Memoization - Cache expensive computations
🌀 Immediately Invoked Function Expressions
IIFE is a function that runs as soon as it is defined, creating a private scope.
Why Use IIFE?
- Avoid polluting global namespace
- Create private variables
- Execute code immediately
- Module pattern before ES6 modules
Modern Alternatives
- ES6 Modules (
import/export) - Block scope with
let/const - Class private fields (#)
🎮 Practice Exercises
Fix the scope issues and implement the closure function.
💪 Additional Challenges:
- Create a counter with increment, decrement, and reset methods
- Implement a memoization function using closure
- Create a module using IIFE with private and public methods
- Fix common hoisting bugs in legacy code
📋 Quick Reference
Scope Types:
var- Function scopelet/const- Block scope- Global - No declaration needed
- Module - ES6 modules
Key Concepts:
- Hoisting - Declarations move up
- TDZ - let/const before declaration
- Closure - Function + environment
- IIFE - (function())()