In this tutorial, we’ll explore the three different ways to declare a variable in JavaScript var
let
const
. The var
available since the beginning of JavaScript. let
const
added in ES6. We’ll also understand var
problematic and we should let
const
.
var
k
Till ES5 var
was the only way to declare variables in JavaScript:
//Declaring variable
var car;
//Initializing variable
car = 'Tesla';
Most of the time we do the declaration and initialization at once:
var car = 'Tesla';
Hey, I know these simple things. They are common across all programming languages.
No, they are not so simple In JavaScript scoping works differently and it causes great confusion and frustrations to beginners There is also the concept of hoisting and shadowing.
If you have no idea of “scopes”, “hoisting” or “shadowing”, don’t panic and read further.
Scope of a variable in JavaScript
The term scope in the programming world refers to the visibility of a variable or other entities. Variables are not visible outside the scope in which they are declared. In JavaScript (till ES5), the scope of a variable is either a global scope or a function scope. Before the ES6, there was no concept of block scope.
Global Scope
Any variable declared outside of a function is of global-scope, which means they can be accessed by any part of the program.
Let us see things in action:
var msg = 'Hello World';
function greet(){
console.log(msg);
}
greet();
Output:
Hello World
In this example variable msg
is defined outside of any function. So it has a global scope. We know that if any variable has a global scope, any part of the program can access it. Hence it is visible inside the function greet()
.
Local Scope (Function Scope)
If a variable is declared inside a function, it is NOT visible outside that function. Even if the variable is declared (using var
) inside a code block (e.g,for
while
Let us take an example:
function greet(){
if(true){
var msg = 'Hello World';
}
console.log(msg);
}
greet();
console.log(msg);
Output:
Hello World
Uncaught ReferenceError: msg is not defined
As we can see the scope of the msg
scope. Although the variable is declared inside if
, it is available outside the local-block within the function. But it is not available outside the function as we can see the Uncaught ReferenceError: msg is not defined
trying to access it outside the function.
It happens due to hoisting.
Hoisting
Where do you hoist a flag?
On the top of the castle.
Let us take an example to understand *hoisting* in JavaScript:
console.log(msg);
var msg = 'Hello World';
Output:
undefined
Wait…! I think we should get the following error because the variable msg was not declared when we tried to access it
Uncaught ReferenceError: msg is not defined
Well, in JavaScript, it does not matter where variables are declared within a particular scope. All variable declarations are moved to the top of their scope.
The above program was translated by the JS interpreter as:
var msg;
console.log(msg);
msg = 'Hello World';
As we can see the variable declaration was hoisted at the top of the scope, global-scope in this case. But the variable assignment was NOT hoisted. The JavaScript interpreter assigned it the default undefined
Hence we got the output undefined
.
The same concept would apply with function scope (local scope). All variable declarations inside a function will be at the top of the function, no matter where they are declared in the function.
function greet(){
if(true){
var msg = 'Hello World';
}
console.log(msg);
}
greet();
console.log(msg);
The above program was translated by JavaScript interpreter as if var msg
was hoisted at the top of the function although it is declared inside the if
block.
function greet(){
var msg;
if(true){
msg = 'Hello World';
}
console.log(msg);
}
greet();
console.log(msg);
Hence we get the output – Hello World
Shadowing
If we declare a local variable and a global variable with the same name, the local variable will take precedence when it is referred inside a function. It is called shadowing, the inner variable shadows the outer variable. The Javascript interpreter searches for the variable at the innermost scope and continues until the first match is found.
var msg = 'Hello ';
var name = 'John';
function greet(){
var msg = 'Julia';
if(true){
console.log(msg + name); //Hello Julia
}
}
greet();
The moment if
is executed by the JavaScript interpreter, it looks for the msg
the local scope. As it is found there, it uses the local scope variable, even if the same variable is declared in the outer scope as well. name
is not found in the inner scope so the JS interpreter tries to find it in the outer scope and it is found.
Scoping and Hoisting works the same for functions as it works with variables.
Issues with var
No that we have understood different concepts related to var
, let us discuss the issues with var and why you should avoid using it.
Let us take an example:
var greetings = 'Hello John';
function greet() {
console.log(greetings); // undefined
if (true) {
var greetings = 'Hello Julia';
console.log(greetings); //Hello Julia
}
console.log(greetings); //Hello Julia
}
greet();
If you are coming from another programming like Java, Python, C# , you must be thinking “what the heck”. Don’t you think as greetings is a global variable the first output should Hello John
And the third output should be Hello John
because although inside if
we have declared the same greetings
should not be visible outside if
?
Incorrect!
We just learned about scoping, hoisting and shadowing in JavaScript. We know there is no concept of block scope in JavaScript(till ES5). Let us apply these learnings for the above example.
When the JavaScript interpreter encounters the variable declaration greetings
the if
, it hoisted the variable declaration at the top of the function. But only the declaration is hoisted, not initialization. The variable has the default undefined
the JavaScript interpreter assigns while declaration. When greetings
is referred inside the first print statement, due to *shadowing* the JavaScript interpreter used the inner declaration of greetings
, not the global one. But since the inner declaration greetings
not initialized yet, it printed its default undefined
Again, the same concept of hoisting and shadowing got applied in the third output. The interpreter took the function-scoped declaration greetings
The only difference is this timegreetings
already inside if
.
As we can see variables declared
var
confusing and prone to introduce bugs in the program, if not written with at most care. And that is the reason you should nevervar
declare variables in your program. Always uselet
orconst
to declare variables.
let
keyword in ES6
The ES6 specification addressed these issues with JavaScript and introduced **block scoping** with a new keyword let
.
Let us take the same example as the previous one with a change – replacing var
with let
keyword :
let greetings = 'Hello John';
function greet() {
console.log(greetings); //Hello John
if (true) {
let greetings = 'Hello Julia';
console.log(greetings); //Hello Julia
}
console.log(greetings); //Hello John
}
greet();
As we see the output is more predictable with let
. The first time greetings
in the print statement, it took the global value because it was not yet declared locally. The JavaScript interpreter declared the second instance greeting
the local scope inside if
. It retains the local Hello Julia
if
. But outside if
in where the variable was declared, the greetings
is not visible to the interpreter. Hence it took the global declaration in the third print statement.
As we see the let
keyword is behaving similar to most of the other programming languages and is having *block scope*. That is the reason we should “mostly” let
to declare variables in JavaScript and never var
const
keyword in ES6
I hope you have noticed the earlier statement – we should “mostly” let
. We have used mostly because when we have variables that are never going to change their value, we should declare them const
. It is a good safety feature because if any part of the program to change the value of the variable, the JavaScript interpreter will raise an Exception.
Let us see things in action:
function greet() {
const greetings = 'Hello World';
if (true) {
greetings = 'Hello Julia';
console.log(greetings);
}
}
greet();
If we run this code, the JavaScript interpreter will raise an Exception where we try to change the value of const
variable greetings
.
Uncaught TypeError: Assignment to constant variable.
at greet (<anonymous>:4:15)
at <anonymous>:9:1
There is no other difference between let
and const
Conclusion
We hope this tutorial gave you a good understanding of all the three ways to declare variables in JavaScript. We discussed var
not have block scope, it is bug prone and we should never use it. We should use S6’s let
const
. We also learned that we should const
we want to restrict a variable so that it never changes its value and remain .