Understanding Scope
Scope is a fundamental concept in JavaScript that determines where variables and functions can be accessed.
function sayHi() {
const result = "Hi"
console.log(result) // Prints "Hi"
}
const result = "Bye"
sayHi() // What does this print?
console.log(result) // What does this print?
What is Scope?
Scope is the area of your code where a variable or function is accessible. JavaScript creates a new scope inside every set of curly braces {} as well as a global scope for your entire file.
function myFunction() {
// New scope created here
const x = 5
}
// Global scope
const x = 10
myFunction()
Scope Is One-Way
The best way to think about scope is like one-way mirrors that always look outward:
✅ Inner scopes can see outer scopes
const a = 1 // Global scope function func() { const b = 2 // Function scope console.log(a) // ✅ Can see outer scope console.log(b) // ✅ Can see own scope }❌ Outer scopes cannot see inner scopes
function func() { const b = 2 // Function scope } func() console.log(b) // ❌ Error - cannot see inner scope
Types of Scope
There are multiple types of scope in JavaScript, but the three most important are global scope, function scope, and block scope.
Global Scope
The global scope is the outermost scope - your entire file. Variables declared here can be accessed from anywhere in your code:
const name = "Kyle" // Global scope
function sayHi() {
console.log(name) // ✅ Can access global variable
}
sayHi()
Block Scope
A new block scope is created for any code between curly braces {}:
function myFunction() {
const x = 3 // New block scope
}
if (true) {
const x = 1 // New block scope
}
{
const x = 2 // New block scope
}
Function Scope
A function scope is created whenever you define a function. A function scope is very similar to a block scope, but some JavaScript features (covered later) use function scope instead of block scope:
function myFunction() {
const x = 5
}
Nested Scopes
You can have multiple levels of scope:
let c = 3 // Global scope
{
// Outer block scope
let a = 1
{
// Inner block scope
let b = 2
console.log(a) // 1 - can see outer scope
console.log(b) // 2 - can see own scope
console.log(c) // 3 - can see global scope
}
console.log(a) // 1 - can see own scope
console.log(c) // 3 - can see global scope
// console.log(b) // ❌ Error - cannot see inner scope
}
Naming Conflicts
You can have variables with the same name in different scopes without conflict:
const result = "Kyle" // Global scope
function sayHi(name) {
const result = "Hi " + name // Block scope - different variable!
console.log(result) // "Hi Kyle"
}
sayHi("Kyle")
console.log(result) // "Kyle" - still the global variable
These are completely separate variables that happen to share a name.
Determining Which Variable to Use
When JavaScript looks for a variable, it starts in the current scope and works outward:
const a = 1 // Global scope
const name = "Kyle" // Global scope
function myFunction() {
const a = 2 // Block scope
console.log(a) // Prints 2
console.log(name) // Prints "Kyle"
}
myFunction()
Best Practices
Minimize global variable usage
// ❌ Avoid this const name = "Kyle" function myFunction() { console.log(name) }// ✅ Put variables as locally as possible function myFunction() { const name = "Kyle" console.log(name) }Don't use the same name for different variables in nested scopes
// ❌ Confusing - hard to tell which 'a' is used const a = 1 function myFunction() { const a = 2 console.log(a) // Which 'a' is this? }// ✅ Clear - use different names const outerA = 1 function myFunction() { const innerA = 2 console.log(innerA) // Clearly uses inner scope }