Understanding the Concept of Scope and How It Affects Variables Declaration in JavaScript

images variables.png

In this article we will talk about the concept of scope in javascript and how it affects the behaviours of the three keywords; let, const and var. In order to make this article simple and concise, I will not touch hoisting. I will write a different article on hoisting in JavaScript as a continuation of this article.

One of the first and most crucial concepts for new programmers to understand is variables because they are a key component of many programming languages. Variables have a variety of different characteristics in JavaScript, as well as a number of naming conventions that must be adhered to. The three keywords var, let, and const are used to declare variables in JavaScript, and each one has a different impact on how the code will interpret the variable.

Variables in JavaScript were formerly solely declared using the var keyword. However, with the release of ES2015 (ES6), two techniques to declare variables, let and const, were introduced. This frequently prompts inquiries, chiefly around the appropriate timing for using a certain keyword:

var firstName = 'Abdulkareem';
const lastName = 'Babatunde';
let job = 'Student';

Differences Between const, let and var

The three ways of declaring variables in JavaScript differ in terms of hoisting, scope and reassignment:

Screenshot 2022-06-29 at 14.49.31.png

To understand this, we need to talk about scope and hoisting. But we will only be exploring the concept of scope in this article.

What is Scope?

Scope-in-JS-Facebook.jpeg

In JavaScript, scope is a crucial topic to understand in order to write code, because it influences the variable keyword you should use. Scope is the space or environment in which a certain variable is declared. Scoping controls how our program's variables are organized and accessed by the javascript engine. Where do variables reside is a question posed by scoping. or "Where can we access this variable and where can't we?"

Let's take a real world example:

In a fintech company, we have the front-end developers, back-end developers and the product designers. They all have a common interest which is basically build a product which can be called the global "interest". The different teams also have their respective tasks or local "interest" which are:

  • Product designers - they come up with a new product design,
  • Front-end developers - they work on the frontend portion of the applications
  • Back-end developers - create and maintan technology at the back end of a website (the server, database and application).

Each team (variable) has its respective task (where they function or can be accessed).

Now let's move on to the types of scopes

Types of Scope

We have 3 types of scope in JavaScript, they are;

  1. Global Scope
  2. Function Scope
  3. Block Scope

Before we talk about each scope, let's also define what the scope of a variable is. The scope of a variable is basically the entire region of our code where a certain variable can be accessed. Note that the scope of a variable is not the same thing as scope. Scope is a region of the program where variables can be declared, while the scope of a variable is its lifetime in the program. This means that the scope of a variable is the block of code in the entire program where the variable is declared, used, and can be modified. Now let's move on to define each of the scope.

Global Scope

Variables that are declared outside any code function or block are known as global variables because they have a global scope. These variables will be accessible everywhere in our program, in all functions and all blocks.

Consider that you have a script file. The scope of any variable declared outside of a function or block is again globally scoped:

const age = 2015;
function calcAge() {
      const currentAge = 2022 - age;
      console.log(`You are ${currentAge}-year old`);
      return currentAge;
}

calcAge();

The expected result is:

Screenshot 2022-06-29 at 13.06.05.png

In the above example, the variable "age" can be accessed and modified anywhere in the file because it is available in the global space. The variable "age" is accessible within the calcAge() function, as it has a global scope. It exists in the context of the application, and the calcAge() function can call on that context.

Function Scope

Each and every function creates a scope. The variables declared inside that function scope are only accessible inside that function. This is also called a local scope as opposed to the global scope.

Let's take a look at the code below with variable "age" declared inside the calcAge() function.

function calcAge() {
    const age = 2015;
    const currentAge = 2022 - age;
    return currentAge;
}

console.log(age);

When you log the variable "age" outside the calcAge() function, you will notice it is not defined because it does not exist in the global scope so there's a reference error. It can be referenced only within the function in which it is defined.

Expected result:

Screenshot 2022-06-29 at 15.28.15.png

Block Scope

Traditionally, only functions used to create scopes in JavaScript. But starting in ES6, blocks also creates scopes now. And with blocks, we mean everything that is between curly braces, such as the block of an if statement or a for loop. So just like with functions, variables declared inside a block are only accessible inside that block and not outside of it.

function calcAge(birthYear) {
    const age = 2037 - birthYear;
    if (birthYear >= 1981 && birthYear <= 1996) {
        const firstName = 'Tunde';

        const str = `Oh, and you're a millenial, ${firstName}`;
        console.log(str);


    } else {
         console.log('error');
}
    console.log(firstName);
    return age;

}

calcAge(1984);

Expected result:

Screenshot 2022-06-29 at 15.57.06.png

You should notice that when we log the variable "firstName" into the console outside the if/else statement block, we got a reference error because it is only accessible within the block scopes.

Now let's go to the interesting part. Now, the big difference is that block scopes only apply to variables declared with let or const. That's why we say that let and const variables are block scoped. So if we declared a variable using var in this block, then that variable would actually still be accessible outside of the block, and would be scoped to the current function or to the global scope. And so we say that var is function scoped.

Let's try the same example above while declaring the variable with let and var as we have previously declared it with const.

Declaring the variable "firstName" with let

function calcAge(birthYear) {
    const age = 2037 - birthYear;
    if (birthYear >= 1981 && birthYear <= 1996) {
        let firstName = 'Tunde';

        const str = `Oh, and you're a millenial, ${firstName}`;
        console.log(str);


    } else {
         console.log('error');
}
    console.log(firstName);
    return age;

}

calcAge(1984);

Expected result:

Screenshot 2022-06-29 at 16.12.28.png

We will get the same error as before when we try to log the variable "firstName" into the console outside the if/else block because let is also block-scoped as const.

Declaring the variable "firstName" with var

function calcAge(birthYear) {
    const age = 2037 - birthYear;
    if (birthYear >= 1981 && birthYear <= 1996) {
        var firstName = 'Tunde';

        const str = `Oh, and you're a millenial, ${firstName}`;
        console.log(str);


    }
    console.log(firstName);
    return age;

}

calcAge(1984);

Expected result:

Screenshot 2022-06-29 at 16.20.03.png

From the above results, we were able to access the variable 'firstName' because it was declared with the keyword var. Variables that are declared using the var keyword are always function-scoped.

Good Coding Practices

  • const is preferable to let, which is preferable to var. Avoid the use of var.

  • When it is known that the value it points to will change over time, let is preferred to const.

  • For global, constant values, const is fantastic.

Conclusion

In this article, we looked at the evolution of JavaScript variable declaration, from the initial var to the more recent let and const.

We've looked at JavaScript scopes and how various declaration signifiers impact a variable's scope in code. Last but not least, we looked at some best practices and noted when to use which keyword.

I hope you have understood the concept of scope and I look forward to writing on hoisting in javascript.

Thank you for reading and don't forget to drop a comment, an emoji or follow me on Twitter: twitter.com/_kareem_tunde.