Block Scope and Shadowing In JS

Block Scope and Shadowing In JS

Hello guys, Welcome to this amazing series of Javascript for interviews, I this blog I will talk about the concept that most beginners have confusion with understanding i.e Block scope and Shadowing, but don't worry I will be explaining them with examples. This blog covers -

  • What is a scope?
  • Why do we need a block?
  • What is block scope?
  • Scope of let, var and const.
  • Shadowing in Javascript.
  • Illegal shadowing in Javascript.

Let's understand the concepts !!

What is a Scope? A scope is a place in Javascript where all variables and functions are present.

What is a block?

The block in Javascript is represented by curly braces({}). And this block is used by Javascript to combine multiple statements into a single statement. this might be confusing but let's see an example of a block.

if(true);

This is a simple if statement that evaluates to true, but if we have to check something or perform operations we will need multiple statements so do perform this after if it requires a set of curly braces in which statements will be present.

if(true){

    var a = 10;
    console.log(10);
}

Now you understand what is a block, now let's see why we need it.

What is the need for a block?

Using the block we can use multiple statements where javascript expects a single output, You can refer the above example where it expects only one value.

if(true){

    var a = 10;
    console.log(10);
}

What is a block scope? It is a scope where all access all variables and functions inside the block.

Now, comes the tricky part of block scope, I will try my best to explain with the help of examples, but to understand how this works you need to know about topics like,

Lexical scoping, Execution context, Hoisting and some basic difference between let, var and const, You can refer to these articles for reference.

Now let's see an example

{
    var a = 10;
    let b = 20;
    const c = 30;

    console.log(a);
    console.log(b);
    console.log(c);
}

Ouput - 10, 20 , 30

As you might have guessed the right answer but what if I try to access the value outside the scope, will they give me the same answer?


{
    var a = 10;
    let b = 20;
    const c = 30;

    console.log(a);
    console.log(b);
    console.log(c);
}

console.log(a);
console.log(b);
console.log(c);

Output - 10,20,30,10

Strange right! Only the value of a gets printed outside the block and it throws reference error for let and const! Well, this is because of the fact that var is present in a global execution context and let, const has a separate execution context, We have seen this in hoisting.

b2.png

So from here can conclude that Let and Const variables are block-scoped.

We have so far seen the block scope and how let,const and var are present in scope now let's see a tricky and interesting topic of shadowing.

What is variable shadowing?

Now, when a variable is declared in a certain scope having the same name defined on its outer scope and when we call the variable from the inner scope, the value assigned to the variable in the inner scope is the value that will be stored in the variable in the memory space. This is known as Shadowing or Variable Shadowing.

First, take a look at how shadowing works in the case of var.

var a = 100;

{
    var a = 10;
    let b = 20;
    const c = 30;

    console.log(a);
    console.log(b);
    console.log(c);
}


console.log(a);

Output - 10,20, 30,10

Here in this example the there is two var with the same name one is outside the scope having a value of 100 and the other is in the scope having a value of 10, I this case the var which is in the scope shadows the var with value as 100. When the code runs the both have reference to the same memory location in the global execution context.

b3.png

Here you can see the value of a is 100 in global space, now if I put a debugger and again run the code the value of a will now be modified to 10, in global memory itself this is because they point to the same memory space.

b4.png

Now the case is not the same for let and const!!

let b = 100;

{

    let b = 20;
    const c = 30;
    console.log(b);
   console.log(c);

}

console.log(b);
console.log(c);

Output - 20 , 30 , 100

Here the let inside the block does not shadow the let outside of the block, something interesting happens when we execute the code!!

b6.png

Here In this case You can see 3 scopes are created one is the script scope (Not a global scope ), In which the let outside of the scope is present and a block scope for let and const and global scope for var.

Here again comes the point that let and const are block-scoped.

I hope you have understood the concepts, Do like and subscribe I will come again with a blog on Closures in this series!!