To understand variables shadowing in JavaScript, first, we need to understand the scope.
In JavaScript, we have global scope, function scope, and block scope.
The scope is something like a box, that has other boxes inside of it. Each box represents a scope. When a variable is scoped, it means that this variable is accessible only inside this scope and in the other scope inside of it. However, these variables are not accessible outside of this scope, the box.
The scope box is a separate memory box and different variables act differently depending on scope. In some scopes, they cannot be accessible outside of it and in some, they can.
The variable declared with var is global-scoped as well as function scope, meaning that if we create a variable inside of a function it will not be accessible outside the function. The let and const keywords are also function scope but at the same time they are also block-scoped, meaning that in a block of code consisting of curly braces like if conditions, switch statements, or loops, they will not be accessible if they were declared inside of them.
If you have not already make sure to read my post about Variable Declarations in JavaScript.
Now, once you understand the scope better let’s understand what shadowing is in JavaScript.
Variable Shadowing
Imagine that you create the exact same variables with the exact same names but different values. But you create them in different scopes. Let’s say you create a variable with the let keyword which is function-scoped. You created exactly the same variables but with different values. The first variable is located in the global scope and the second one is in the function scope.
As you see I have two console logs. What will be logged to the console? Which value is it going to be, apple or orange?
First, it will be orange, then it will be an apple. Why?
Because when we declare a variable in a scope where we also have the same variable in the outer scope, the value assigned in the inner scope is the value that will be stored in the memory. The inner scope usually is supposed to have access to the outer scope however when we declare the same variable things change.
Our outer scope is global scope in this example and our inner scope is function scope. This is called shadowing or variable shadowing in JavaScript. The inner scope variable shadowed the outer scope variable.
But why is the result value apple in the second console log?
Because the variable will be gone from the memory when the function ends and it doesn’t go outside of it.
The same applies to block scope because the let keyword is also block-scoped.
Now, let's use the same example but use var inside a function scope. The var keyword is also function scoped so it will behave the same way.
And also use a var but in a block scope this time. As a reminder, var is not block-scoped so it isn’t trapped there.
As you see, things change here. The var keyword value changed because it is not block scoped and it’s not trapped there. As a result, no variable shadowing happens here.
Illegal Shadowing
Besides just shadowing, we also have illegal shadowing in JavaScript. It means that we have some restrictions.
If you create a variable in a global scope with the let keyword and another variable with the var keyword in a block scope but the exact same name, it will throw an error. This is called illegal shadowing.
This happens because let and var both technically have the same scope meaning that the variable name fruit already exists there. The variable declared with the var in the block scope is not scoped and is accessible from the outside.
Is variable shadowing good or bad?
If we already had some variable and we shadowed it inside another scope, we are losing access to the original variable and will not receive the output we need inside another scope. Shadowing can lead to unneeded bugs and results and will be harder to debug when you have many variables.
That’s why it’s always better to name variables in a more explanatory way, so it describes their purpose. It’s also recommended to keep the code organized and group the variable declaration together, instead of spreading them across the code. By having all variables together, it will be easier to notice if you are creating anything with the same name.
In conclusion, understanding variable shadowing in JavaScript is important as it affects the accessibility and behavior of variables within a scope. Variable shadowing occurs when an inner scope declares a variable with the same name as an outer scope. This results in the inner scope’s variable overriding the outer scope’s variable and shadowing it. However, it’s essential to avoid illegal shadowing, which occurs when two variables with the same name are declared within the same scope using different keywords, such as let and var. Shadowing can lead to bugs and confusing results, so it’s recommended to use descriptive names for variables and keep them organized.