JavaScript Variable Scope
In JavaScript, variable scope determines where variables are accessible. Understanding the difference between var, let, and const along with function and block scope is critical for writing reliable code.
What You'll Learn
In this section, you’ll learn how variable scoping works in JavaScript using different keywords and scope types, such as global, function, and block scope.
Understanding Variable Scope
In JavaScript, scope defines where variables can be accessed or modified in your code. JavaScript primarily has the following types of scope:
- Global Scope: A variable declared outside of any function or block is accessible from anywhere in the program.
- Function Scope: Variables declared using var inside a function are only accessible within that function.
- Block Scope: Variables declared with let or const are limited to the block ({}) in which they are defined.
When JavaScript looks for a variable, it searches in the following order:
- First, the local scope – inside the current function or block.
- Then, the outer function scope – if the function is nested inside another.
- Finally, the global scope – variables declared outside of any function or block.
Example 1: Global Scope
Variables declared outside of any function or block have global scope and can be accessed from anywhere in the program.
var x = 10; // Global variable
function showValue() {
console.log(x);
}
showValue();
var x = 10; // Global variable
function showValue() {
console.log(x);
}
showValue();
How It Works:
- x = 10: The variable x is declared outside of any function, making it a global variable.
- console.log(x): Inside the showValue function, we access and print the global variable x.
Output
10
10
Example 2: Function Scope
Variables declared with var inside a function are only accessible within that function. This is known as function scope.
function myFunction() {
var y = 5; // Function-scoped variable
console.log(y);
}
myFunction();
// console.log(y); // Uncaught ReferenceError: y is not defined
function myFunction() {
var y = 5; // Function-scoped variable
console.log(y);
}
myFunction();
// console.log(y); // Uncaught ReferenceError: y is not defined
How It Works:
- var y = 5: The variable y is declared inside the function myFunction, making it local to that function.
- console.log(y): Prints the value of y from within the function.
- console.log(y) (outside the function): This would result in an error because y is not accessible outside the function.
Output
5
5
Example 3: Block Scope
Variables declared with let and const are limited to the block in which they are defined, whether that’s a loop, conditional, or any other block denoted by {}.
{
let a = 10; // Block-scoped variable
const b = 20; // Block-scoped constant
console.log(a); // Accessible here
console.log(b); // Accessible here
}
// console.log(a); // Uncaught ReferenceError: a is not defined
// console.log(b); // Uncaught ReferenceError: b is not defined
{
let a = 10; // Block-scoped variable
const b = 20; // Block-scoped constant
console.log(a); // Accessible here
console.log(b); // Accessible here
}
// console.log(a); // Uncaught ReferenceError: a is not defined
// console.log(b); // Uncaught ReferenceError: b is not defined
How It Works:
- let a = 10: The variable a is declared inside the block, making it accessible only within that block.
- const b = 20: Similarly, b is block-scoped, and cannot be accessed outside the block.
- Accessing a and b outside the block results in an error because they are not available outside their scope.
Output
10
20
10
20
Example 4: Global, Local, and Block Scope
This example demonstrates how global, local, and block scopes work in JavaScript. Each type of scope controls the visibility of variables in different parts of your code.
- var – function-scoped, can be redeclared, hoisted as undefined.
- let – block-scoped, cannot be redeclared, hoisted but not accessible before declaration.
- const – block-scoped, must be initialized, cannot be reassigned.
// Global Scope
var globalVar = "I'm a global variable"; // Accessible anywhere
function demonstrateScopes() {
// Local Scope
var localVar = "I'm a local variable"; // Accessible only within this function
// Block Scope
if (true) {
let blockVar = "I'm a block-scoped variable"; // Accessible only inside this block
console.log(blockVar); // Output: I'm a block-scoped variable
}
// console.log(blockVar); // Uncaught ReferenceError: blockVar is not defined
console.log(localVar); // Output: I'm a local variable
console.log(globalVar); // Output: I'm a global variable (accessed from global scope)
}
demonstrateScopes();
console.log(globalVar); // Output: I'm a global variable
// console.log(localVar); // Uncaught ReferenceError: localVar is not defined
// Global Scope
var globalVar = "I'm a global variable"; // Accessible anywhere
function demonstrateScopes() {
// Local Scope
var localVar = "I'm a local variable"; // Accessible only within this function
// Block Scope
if (true) {
let blockVar = "I'm a block-scoped variable"; // Accessible only inside this block
console.log(blockVar); // Output: I'm a block-scoped variable
}
// console.log(blockVar); // Uncaught ReferenceError: blockVar is not defined
console.log(localVar); // Output: I'm a local variable
console.log(globalVar); // Output: I'm a global variable (accessed from global scope)
}
demonstrateScopes();
console.log(globalVar); // Output: I'm a global variable
// console.log(localVar); // Uncaught ReferenceError: localVar is not defined
How It Works:
- var globalVar: Declared outside of all functions, this is a global variable accessible anywhere in the program.
- var localVar: Declared inside the demonstrateScopes function, this is a local variable and cannot be accessed outside of the function.
- let blockVar: Declared inside an if block using let, this is a block-scoped variable and can only be accessed within that block.
- Trying to access blockVar or localVar outside their respective scopes will result in a ReferenceError.
Output
I'm a block-scoped variable
I'm a local variable
I'm a global variable
I'm a global variable
I'm a block-scoped variable
I'm a local variable
I'm a global variable
I'm a global variable
Example 5: Function Scope vs Block Scope
In JavaScript, variables declared with var are function-scoped, while variables declared with let and const are block-scoped. This example shows how they behave differently within blocks.
function testScope() {
if (true) {
var functionScoped = "I am function scoped";
let blockScoped = "I am block scoped";
}
console.log(functionScoped); // Works: var is function scoped
// console.log(blockScoped); // Error: blockScoped is not defined
}
testScope();
function testScope() {
if (true) {
var functionScoped = "I am function scoped";
let blockScoped = "I am block scoped";
}
console.log(functionScoped); // Works: var is function scoped
// console.log(blockScoped); // Error: blockScoped is not defined
}
testScope();
How It Works:
- var functionScoped: Declared inside an if block, but still accessible anywhere inside the function because var is function-scoped.
- let blockScoped: Declared with let inside the if block and accessible only within that block due to block scoping.
- Trying to access blockScoped outside the block causes a ReferenceError.
Output
I am function scoped
I am function scoped
Example 6: Variable Shadowing
Variable shadowing occurs when a variable declared in an inner scope has the same name as a variable in an outer scope. The inner variable temporarily "shadows" the outer one within its scope.
let message = "Global message"; // Global scope
function displayMessage() {
let message = "Local message"; // Shadows the global variable within this function
console.log(message); // Outputs: "Local message"
}
displayMessage();
console.log(message); // Outputs: "Global message"
let message = "Global message"; // Global scope
function displayMessage() {
let message = "Local message"; // Shadows the global variable within this function
console.log(message); // Outputs: "Local message"
}
displayMessage();
console.log(message); // Outputs: "Global message"
How It Works:
- let message = "Global message": Declares a variable in the global scope.
- let message = "Local message": Declares a new variable with the same name in the local scope of the function, shadowing the global one.
- console.log(message) inside the function prints the local version, while the one outside prints the global version.
Output
Local message
Global message
Local message
Global message
Example 7: Hoisting
In JavaScript, variable and function declarations are moved to the top of their scope before code execution. This is known as hoisting. However, how var, let, and const behave when hoisted is different.
console.log(a); // Outputs: undefined (due to hoisting)
var a = 5;
console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 10;
console.log(c); // ReferenceError: Cannot access 'c' before initialization
const c = 15;
console.log(a); // Outputs: undefined (due to hoisting)
var a = 5;
console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 10;
console.log(c); // ReferenceError: Cannot access 'c' before initialization
const c = 15;
How It Works:
- var a: The declaration is hoisted to the top of the scope, but not the assignment. So a exists and is undefined when logged.
- let b and const c: These are hoisted but remain in a "temporal dead zone" until their declaration is evaluated. Accessing them before declaration results in a ReferenceError.
Output
undefined
ReferenceError: Cannot access 'b' before initialization
ReferenceError: Cannot access 'c' before initialization
undefined
ReferenceError: Cannot access 'b' before initialization
ReferenceError: Cannot access 'c' before initialization
Exercises
Try the following exercises to practice how scope works in JavaScript. Test your understanding of global, local, block scope, shadowing, and hoisting.
1. Create a function that uses both a global and a local variable.
// Global variable
let globalName = "Alice";
function greet() {
// Local variable
let greeting = "Hello";
console.log(greeting + ", " + globalName + "!");
}
greet();
// Global variable
let globalName = "Alice";
function greet() {
// Local variable
let greeting = "Hello";
console.log(greeting + ", " + globalName + "!");
}
greet();
2. Write a function where a block-scoped variable is not accessible outside the block.
function checkAge() {
if (true) {
let age = 25;
console.log("Inside block:", age);
}
// console.log("Outside block:", age); // Uncomment this line to see the error
}
checkAge();
function checkAge() {
if (true) {
let age = 25;
console.log("Inside block:", age);
}
// console.log("Outside block:", age); // Uncomment this line to see the error
}
checkAge();
3. Test how hoisting works by logging a var variable before and after declaration.
console.log(myVar); // Outputs: undefined due to hoisting
var myVar = "Hoisted variable";
console.log(myVar); // Outputs: Hoisted variable
console.log(myVar); // Outputs: undefined due to hoisting
var myVar = "Hoisted variable";
console.log(myVar); // Outputs: Hoisted variable
*Tip: After completing each exercise, try modifying the code to see how different scopes affect accessibility and errors.
Frequently Asked Questions
What is variable scope in JavaScript?
What is variable scope in JavaScript?
In JavaScript, variable scope refers to the accessibility of a variable in different parts of the code. Variables can either be global or local based on where they are declared.
What is the difference between global and local scope?
What is the difference between global and local scope?
Global scope refers to variables that are declared outside of any function, meaning they are accessible throughout the entire program. Local scope refers to variables declared inside a function, and they are only accessible within that function.
What is block scope in JavaScript?
What is block scope in JavaScript?
Block scope in JavaScript refers to variables that are declared within a block of code, such as inside a loop or an if statement, using the let
or const
keywords. These variables are only accessible within the block they are defined.
Can I access a variable declared inside a function outside of that function?
Can I access a variable declared inside a function outside of that function?
No, variables declared inside a function are scoped to that function. This means they cannot be accessed outside the function.
What is the var
keyword and how does it differ from let
and const
?
What is the var
keyword and how does it differ from let
and const
?
var
is function-scoped, meaning the variable is accessible throughout the entire function in which it is declared, regardless of block structure. In contrast, let
and const
are block-scoped, meaning they are only accessible within the block they are declared.
What's Next?
Next, you'll dive into anonymous and arrow functions in JavaScript. These function types offer a more concise and expressive way to write functions, improving the readability and efficiency of your code.