IntroFunction Scope vs Block ScopeWhat is Scope?What is Function Scope?What is Block Scope?varScope HoistingReassigning the valueRedeclaration of the variableletScopeHoistingReassigning the valueRedeclaration of the variableconst ScopeHoistingReassigning the valueRedeclaration of the variableConclusion
Intro
In JavaScript, variables can be declared using three different methods:
var
, let
, 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
var
, let
, 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
var
,let
, andconst
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
andconst
are the modern ways to declare variables, which also get hoisted but don't initialise.