Understanding Different Scope Levels in Javascript

Fruitful EjiroFruitful Ejiro
5 min read

The First question we must address is the "Definition of Scope". In Javascript and most other programming languages, your code executes within a designated scope.
Scope refers to the part of a program where a variable, function, and various other identifiers are accessible during the runtime of a program. It details the exact section of your code where you can read and utilize a particular variable or function, ensuring a structured and organized approach to managing data and behavior throughout the codebase.

There are 4 types of scope in Javascript: Global Scope, Module Scope, Block Scope, and Function Scope.
Understanding and managing scope is fundamental for writing code that is predictable, maintainable, clean, and bug-free. This article will explain each scope and highlight their difference and how they work with examples.

SCOPE LEVELS

GLOBAL SCOPE

This is the simplest to understand and it is used by most developers when getting started as it envelops the entire program and is accessible in any part of your application. This means you can read and modify global variables from functions, other blocks, and even in another javascript file in the same application.

Consider this example:

<!--index.html-->

<script src="./script.js"></script>
<script src="./index.js"></script>
// Script.js

const color = 'green';
const colorPicker = () => {
    console.log(color);
    //Prints green
}
//index.js

console.log(color);
//Prints Green

The variable color can be accessed both inside the colorPicker function and another javascript file linked to the same HTML file.

Global variables persist for the entire duration of the program's execution, from the moment the script starts running until it concludes.
However, it's essential to take precautions when using global variables. Issues such as naming conflicts and unintentional changes can arise, especially in larger applications.

MODULE SCOPE

This is similar to Global scope but with a minor difference that is it can only be accessed in the module in which it is defined.
A module is a self-contained unit of code that typically represents a file or a related set of files. It allows for better organization, and code reusability, and prevents pollution of the global scope by keeping variables and functions scoped within the module. To access the module scope, you must specify type="module" within your script tags.

Using the above example:

<script type="module" src="./script.js"></script>
<script type="module" src="./index.html"></script>
// Script.js

const color = 'green';
//index.js

console.log(color);
//Error: color is not defined

The color variable could no longer be accessed in the index.js file because it can now only be accessed in the script.js file due to the module scope

The use of module scope and the module pattern helps in organizing code, reducing the risk of naming conflicts, and promoting code reusability.

BLOCK SCOPE

Introduced in ES6 with the let and const, block scope is a scope in programming where variables and identifiers are accessible within a specific block of code, typically defined by curly braces {}. In languages that support block scope, variables defined within a block are only accessible within that block and any nested blocks inside it. These variables can be declared using let and const keywords, providing block scope. When a variable is declared using let or const inside a block, it is only accessible within that block and any nested blocks inside it.
It is important to note that blocks can also be nested and each nested block creates a new scope. Variables defined in an outer block are accessible in inner blocks, but variables defined in an inner block cannot be accessible in outer blocks.

if (true) {
  let color = 'green';
  console.log(color);  // Accessible within this block

  if (true) {
    console.log(color);  // Accessible in nested blocks
    let fruit = 'Mango';
    console.log(fruit);  // Accessible within this block
  }

  console.log(fruit);  // Error: fruit is not define
}

console.log(color);  // Error: color is not defined
console.log(fruit);  // Error: fruit is not defined

The color variable can be accessed anywhere inside the first if block, including the nested if block, but the fruit variable can only be accessed inside the nested if block, and both cannot be accessed outside of the if blocks.

Block scope helps to enhance code clarity, prevent variable name conflicts, and allows for more precise control over variable lifetimes. It's commonly used in loops and conditional statements to limit variable visibility to specific blocks, improving code clarity and preventing unintended side effects. It's a fundamental feature in modern programming languages for writing clean and maintainable code.

FUNCTION SCOPE

Function scope is similar to block scope, and pertains to variables declared using the var keyword within a function. This gives these variables function-level scope, meaning they are confined to the specific function in which they are defined. In essence, variables established within a function remain invisible beyond that function's boundaries and are not accessible from external functions or code blocks.

Unlike block scope, where variables within nested blocks are isolated, function scope behaves differently. Variables declared in nested blocks can be accessed by the parent block, allowing for wider accessibility within the function.

if (true) {
  var color = 'green';
  console.log(color);  // Accessible within this block

  if (true) {
    console.log(color);  // Accessible in nested blocks
    var fruit = 'Mango';
    console.log(fruit);  // Accessible within this block
  }

  console.log(fruit);  // Accessible within this block
}

console.log(color);  // Error: color is not defined
console.log(fruit);  // Error: fruit is not defined

This example is the same as the block scope example, but using the function scope, the fruit variable can now be accessed within the parent block, but both the fruit and color variables are still inaccessible outside the code block.

Function Scope vs Block Scope:

function exampleFunction() {
  if (true) {
    var flowers = 'Rose Flower';
    let trees = 'Oak Tree';
    console.log(flowers);  // Accessible within the function
    console.log(trees);  // Accessible within this block
  }

  console.log(flowers);  // Accessible within the function
  console.log(trees);  // Error: trees is not defined
}

console.log(flowers);  // Error: flowers is not defined
console.log(trees);  // Error: trees is not defined

Function scope plays a critical role in isolating variables and preventing them from interfering with other sections of the code. Nevertheless, it's important to acknowledge that modern JavaScript introduces block scope through let and const, enhancing the ability to restrict variable visibility within specific code blocks. This provides greater control over variable lifetimes and mitigates the likelihood of inadvertent variable leakage.

Conclusion

Understanding and utilizing these different scopes in JavaScript is vital for well-organized and maintainable code. These scopes regulate the visibility and accessibility of variables and functions in modern JavaScript, particularly the introduction of block scope using let and const, enhancing control and reducing unintended side effects.

Reference:

https://blog.webdevsimplified.com/2022-10/js-scoping/

27
Subscribe to my newsletter

Read articles from Fruitful Ejiro directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Fruitful Ejiro
Fruitful Ejiro

Web Developer ๐ŸŒ