Chapter 13 of 31

JavaScript Scope

When we create variables and functions in JavaScript, an important question comes up:

Where can I use this variable?

For example, a variable created inside a function shouldn't normally be accessible from outside that function.

This concept is called scope.

What is Scope?

Scope determines where a variable or function can be accessed in a JavaScript program.

In simple words, scope tells us the area of the program where a particular variable is available.

For example:

function greet() {
    let message = "Hello";

    console.log(message);
}

greet();

Here, message is available inside the greet() function.

But this won't work:

function greet() {
    let message = "Hello";
}

console.log(message); // ❌ Error

Why? Because message exists only inside the function.


Types of Scope in JavaScript

The main scopes you'll encounter are:

Scope

Meaning

Global Scope

Available throughout the program

Function Scope

Available inside a function

Block Scope

Available inside a block {}

Module Scope

Available within a JavaScript module

Let's understand the important ones.


1. Global Scope

A variable declared outside any function or block is in the global scope.

let name = "John";

function greet() {
    console.log(name);
}

greet();

Output:

John

The name variable is available inside the function because it was created in the outer/global scope.

Global variables can be accessed from many parts of your program, but you should avoid creating unnecessary global variables because they can make larger programs harder to manage.


2. Function Scope

Variables declared inside a function are generally available only inside that function.

function calculate() {
    let result = 100;

    console.log(result);
}

calculate();

This works.

But:

function calculate() {
    let result = 100;
}

console.log(result); // ❌ Error

The variable result belongs to the function's scope.

This is known as function scope.


3. Block Scope

A block is code surrounded by curly braces {}.

For example:

if (true) {
    let message = "Hello";

    console.log(message);
}

The message variable exists inside that block.

Trying to access it outside:

if (true) {
    let message = "Hello";
}

console.log(message); // ❌ Error

will cause an error.

The same applies to const:

{
    const age = 20;
    console.log(age);
}

age is available only inside that block.


let and const vs var

This is an important difference.

let and const are block-scoped.

if (true) {
    let x = 10;
    const y = 20;
}

console.log(x); // ❌ Error
console.log(y); // ❌ Error

However, var is function-scoped, not block-scoped.

if (true) {
    var x = 10;
}

console.log(x);

Output:

10

This is one reason modern JavaScript generally prefers let and const over var.


Nested Scope

Scopes can exist inside other scopes.

For example:

let name = "John";

function greet() {
    let message = "Hello";

    if (true) {
        let age = 20;

        console.log(name);
        console.log(message);
        console.log(age);
    }
}

The innermost block can access variables from its outer scopes.

You can think of it like this:

Global Scope
    ↓
Function Scope
    ↓
Block Scope

An inner scope can generally access variables from its outer scope.


Scope Chain

JavaScript uses something called the scope chain to find variables.

Consider:

let name = "John";

function greet() {
    let message = "Hello";

    console.log(name);
    console.log(message);
}

When JavaScript sees:

console.log(name);

it first looks for name inside the current function scope.

It doesn't find it there, so it looks in the outer scope.

It finds:

let name = "John";

and uses that value.

So JavaScript searches from the current scope outward until it finds the variable.


Variable Shadowing

Sometimes an inner scope creates a variable with the same name as a variable in an outer scope.

This is called shadowing.

let name = "John";

function greet() {
    let name = "Alex";

    console.log(name);
}

greet();
console.log(name);

Output:

Alex
John

Inside the function, JavaScript uses the local name.

Outside the function, it uses the global name.

The inner variable shadows the outer one.


Scope in Loops

Block scope is especially useful with loops.

for (let i = 1; i <= 3; i++) {
    console.log(i);
}

The variable i exists only within the loop.

This won't work:

for (let i = 1; i <= 3; i++) {
    console.log(i);
}

console.log(i); // ❌ Error

This helps prevent variables used for loops from accidentally interfering with other parts of the program.


Scope and Functions

Functions themselves can also access variables from their surrounding scope.

For example:

let message = "Hello";

function greet() {
    console.log(message);
}

greet();

Output:

Hello

The function can access message because message exists in its outer scope.

This behavior becomes especially important when we learn closures later.


A Practical Example

Suppose we're building a simple application:

const appName = "My App";

function login() {
    const username = "John";

    console.log(appName);
    console.log(username);
}

login();

Here:

  • appName is available globally.

  • username exists only inside login().

  • The login() function can access appName from its outer scope.

But code outside login() cannot directly access username.

This kind of separation helps keep variables organized and prevents accidental changes.

Conclusion

Scope determines where variables and functions can be accessed.

The most important concepts to remember are:

Global Scope   → Available throughout the relevant program/module
Function Scope → Available inside a function
Block Scope    → Available inside a block

And remember:

  • let and const are block-scoped.

  • var is function-scoped.

  • Inner scopes can generally access variables from outer scopes.

  • An inner variable can shadow an outer variable.

Understanding scope is extremely important because it becomes the foundation for concepts like closures, callbacks, modules, and asynchronous JavaScript.