var, let and const in JavaScript

var, let and const in JavaScript

Published
November 24, 2022
 

Intro

 
In JavaScript, variables can be declared using three different methods: varlet, and const. In this blog we will understand the differences between them and also look a few examples to make this concept clear.
 
A lot of new features were added with ES6 and one of them was the addition of let and const which we can use to declare variables.
 

Function Scope vs Block Scope

 
Before we jump into the difference between let and var and const, lets understand what function-scope and block-scope mean and the differences between them.
 

What is Scope?

 
Scope simply means where our variable will be available to use inside our code and where it will not.
 

What is Function Scope?

 
Let’s understand this with the of this example.
 
function printName() { var myName = "Vedanth"; console.log(myName); } printName(); //output => "Vedanth" console.log(myName); //output => ReferenceError
 
In the example above, we have a function printName() inside the function, we declare a variable myName and print the variable myName on the console.
 
When we call our function printName it successfully prints the value of variable myName on the console, but when we try to print the variable myName outside the function, it throws referenceError because variable myName has a function scope that's why it can not accessible outside the function. This means that it is available and can be accessed only within that function, this is what Function Scope means.
 

What is Block Scope?

 
Block means a pair of curly brackets {} , a block can be anything that contains an opening and closing curly bracket. Variables having Block Scope will only be available to use inside the block it was declared in, it will not be accessible outside the block, and will give Reference Error if we try to access it outside the block.
 
Let’s understand this with the of this example.
 
if(true) { let myName = "Vedanth"; console.log(myName); //output=> "Vedanth" } console.log(myName); //output => ReferenceError
 
In the example above, we have an if block with a true condition, and inside the if block, we declare a variable name myName. Now when we try to print the myName variable to the console inside the block, it prints successfully, but when we try to print the variable outside the if block, we get a Reference Error. This means that it is available and can be accessed only within that block, this is what Block Scope means.
 
Now that we know the difference between Function Scope and Block Scope lets take a look at the differences between varlet, and const.

var

 
Before ES6 the only way we could declare variables was using the var keyword, but declaring variables with var can cause some issues, before we address these issues lets look how variables declared using var behave.
 

Scope

 
Variables declared with var are Function Scope or Global Scope. The scope is global when a var variable is declared outside a function. This means that any variable that is declared with var outside a function block is available for use in the whole window.
 
var is function scoped when it is declared within a function. This means that it is available and can be accessed only within that function.
 
Lets take a look at this example of var with Function Scope.
 
function printName() { var myName = "Vedanth"; console.log(myName); } printName(); //output => "Vedanth" console.log(myName); //output=> ReferenceError
 
Lets take a look at this example of var with Global Scope.
 
var myName = "Vedanth"; function printName() { console.log(myName); } printName(); //output => "Vedanth" if(true) { console.log(myName); //output => "Vedanth" } console.log(myName); //output => "Vedanth"
 
In this above example, we have a variable myName which is declared outside the function body, and that's why it is Global Scoped.
 
Now, when we try to access this variable inside our function myFun, it print's the variable into the console, then we have an if block with the condition of true; inside this if block, we again print the variable myName to the console and it's accessible here also.
 
The last thing we do is to directly access the variable, and we successfully access the variable and print it on the console.
 
As we can see, the variable myName is accessible everywhere inside our program because it has Global Scope.
 

Hoisting

 
In JavaScript Hoisting refers to the process whereby the interpreter appears to move the declaration of functions, variables or classes to the top of their scope, prior to execution of the code.
 
When we declare a var variable, it gets hoisted to the top of the scope and gets assigned the value of undefined.
 
Let's take a look at this example:
 
console.log(myName); //output => undefined var myName = "Vedanth";
 
So var variables are hoisted to the top of their scope and initialised with a value of undefined.
 

Reassigning the value

 
We can reassign the value of variables that are declared using var.
 
Let’s take a look this example.
 
var name = "Vedanth"; var myAge = 22; if(myAge > 18) { name = "John"; } console.log(name); //output => "John"
 
Here we have a name variable, an age variable, and an if conditional block, our if condition is true here, so code inside the if block will run and reassign the previously declared name variable because of the behaviour of var keyword.
 

Redeclaration of the variable

 
We can redeclare variables that are created using the var keyword. This is also one of the issues with declaring variables with var.
 
Let’s take a look this example.
 
var name = "Vedanth"; var name = "John"; console.log(name); //output => "John"
 
Here we have two name variables, when we declared the name variable again with the value “John” and try to print the value onto the console it will print “John”. This is a problem as we can declare more than one variable of the same name and this can cause errors and bugs in the code.
 
We have looked at how variables declared with var behave and the issues with them. To deal with these issues let and const were introduced.
 

let

 
The new version of javascript (ES6) introduced this method of declaring variables with the let keyword.
 

Scope

 
The let keyword is Block Scoped. This means let variable will be accessible only inside the block it's declared if we try of access outside of the scope, it will show a Reference Error.
 
Lets look at this example.
 
let myAge = 20; if(myAge > 18) { let myName = "Vedanth"; console.log(myName) //output => "Vedanth" } console.log(myName); //output => ReferenceError
 

Hoisting

 
Variables declared using the let keyword also get hoisted, but if we try to access the variable declared with let keyword before initialisation it will throw TBZ (Temporal Dead Zone) error. Unlike var which is initialised as undefined, the let keyword is not initialised. So if you try to use a let variable before declaration, you'll get a Reference Error.
 
console.log(myName); //output => ReferenceError let myName = "Vedanth";
 
The above example we are trying to access a variable myName before the declaration but get ReferenceError or TBZ (Temporal Dead Zone) error because we are trying to access the variable before initialisation.
 

Reassigning the value

 
We can reassign the value of variables declared using the let keyword.
 
Lets look at this example.
 
let myAge = 20; myAge = 21 console.log(myAge) // 21
 
This works and we can reassign the previously declared myAge variable because of the behaviour of let keyword.
 

Redeclaration of the variable

 
Variables declared using the let keyword don’t allow re-declaration of the variable . let keyword introduces a special feature that does not allow re-declaration of variables, if you remember, re-declaration was a problem with variables declared using the var keyword but the let keyword solves this problem. Let’s take a look at this example.
 
let myName = "my name"; let myName = "not my name"; console.log(myName); //output => SyntaxError: redeclaration of let name
 
In the example above, we declared a variable myName and again declared a variable with the same name when we tried to print the variable on the console it throws a SyntaxError: redeclaration of let name
 
 
Now that we know how var and let behave lets understand how variables declared using the const keyword behave.
 

const

 
The new version of javascript (ES6) another new method of declaring variables in javascript using the const keyword to declare constant variables. Variables declared using the const keyword behave the same as let, the only difference is variables declared using the const keyword can't be updated or re-declared; this behaviour of const variable helps us to write error-free code.
 

Scope

 
The const keyword is Block Scoped. This means variables declared using the const keyword will be accessible only inside the block it's declared if we try of access outside of the scope, it will show a Reference Error.
 
Lets look at this example.
 
const myAge = 20; if(myAge > 18) { const myName = "Vedanth"; console.log(myName) //output => "Vedanth" } console.log(myName); //output => ReferenceError
 

Hoisting

 
Variables declared using the const keyword also get hoisted, but if we try to access the variable declared with const keyword before initialisation it will throw TBZ (Temporal Dead Zone) error. Unlike var which is initialised as undefined, the const keyword is not initialised. So if you try to use a const variable before declaration, you'll get a Reference Error.
 
console.log(myName); //output => ReferenceError const myName = "Vedanth";
 
The above example we are trying to access a variable myName before the declaration but get ReferenceError or TBZ (Temporal Dead Zone) error because we are trying to access the variable before initialisation.
 
 

Reassigning the value

 
We can not reassign the value of variables declared using the const keyword.
 
Lets look at this example.
 
const myAge = 20; myAge = 21 console.log(myAge) //output => TypeError: invalid assignment to const 'myName'
 
This works and we can reassign the previously declared myAge variable because of the behaviour of const keyword.
 

Redeclaration of the variable

 
Variables declared using the const keyword don’t allow re-declaration of the variable . const keyword introduces a special feature that does not allow re-declaration of variables, if you remember, re-declaration was a problem with variables declared using the var keyword but the const keyword also solves this problem. Let’s take a look at this example.
 
const myName = "my name"; const myName = "not my name"; console.log(myName); // TypeError: invalid assignment to const 'myName'
 
In the example above, we declared a variable myName and again declared a variable with the same name when we tried to print the variable on the console it throws a TypeError: invalid assignment to const 'myName'
 
We have now understood how variables declared using var , let and const behave. Below is a table to summarise the differences.
 
var
let
const
var has the function or global scope.
let's have the block scope.
const variable has the block scope.
It gets hoisted to the top of its scope and initialised undefined.
It also got hoisted to the top of its scope but didn't initialise. Will throe a TBZ error if we try to access it before
It also got hoisted to the top of its scope but didn't initialise. Will throe a TBZ error if we try to access it before
It can be updated or re-declared.
It can only be updated and can't be re-declared.
It can't be updated or re-declared.
It's an old way to declare a variable.
It's a new way to declare variables introduced in ES6.
It's also a new way to declare a variable, which introduces in ES6.
 
Before we finish lets take a look at one last example.
 
for(var i = 0 ; i < 5; i++){ setTimeout(() => { console.log(i) }, i * 1000) }
 
What will be the output of this code
 
Answer
It will be the number 5 five times. This is because we are declaring i using the var keyword, and as we discussed earlier var is Function Scoped, there is only one reference of the i variable and after the loop runs 5 times the value of i at this point is 5 therefore it prints 5 five times on the console.
5 5 5 5 5
 
How can we fix this ? By using let, as let is Block Scoped, it will create a new instance of the i variable each time the loop runs and there it will print 0,1,2,3,4
 
for(let i = 0 ; i < 5; i++){ setTimeout(() => { console.log(i) }, i * 1000) } /* 0 1 2 3 4 */
 
Okay how can we fix this without using let and still use var
 
const printNumber = (i) => { setTimeout(() => { console.log(i) }, i * 1000) } for(var i = 0 ; i < 5; i++){ printNumber(i) }
By extracting the printing logic into a function that takes i as argument , we will have new instance of i every time the function runs and therefore this will print 0,1,2,3,4.
 

Conclusion

 
  • varlet, and const are keywords that allow us to declare variables.
  • Scope of a variable tells us where we can access this variable inside our code and where we can't. It is one of the decisive reasons for the difference between let and var and const in javascript.
  • var is a nice older way to declare a variable.
  • let and const are the modern ways to declare variables, which also get hoisted but don't initialise.