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.

javascript
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

Example 2: Function Scope

Variables declared with var inside a function are only accessible within that function. This is known as function scope.

javascript
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

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 {}.

javascript
{
    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

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.
javascript
// 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

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.

javascript
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

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.

javascript
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

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.

javascript
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

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.
javascript
// 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.
javascript
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.
javascript
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?

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?

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?

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?

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?

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.