Since the advent of ES6 in 2015, we can agree that a lot of JavaScript developers have become familiar with the use of its features. Although, this may not be entirely true, and it is possible some of the features added may be a mystery to some.
Amongst the features added to ES6 is the let and const, which is used for variable declaration. If you are not clear of the distinction between these two then this article is for you.
Here, we will be discussing var, let and const with respect to their scope, use, and hoisting.
Var
Var declarations was the mainly used for declarations before the introduction of Es6 and due to the issues associated with using var, that was why there was a need to introduce a new way to declare variables.
First, let's talk more about var before we discuss those issues.
Scope of var
var variables are classified into two scopes, global and function/locally scope.
A var variable is considered global when declared outside a function. While a var variable is a function/locally scope when it is declared within a function. This means that it can only be accessed within that function. The examples below are given to aid your understanding.
var number = "twenty";
function anyFunction() {
var alphabet = "a";
}
In this example, number is globally scoped because it exists outside a function while alphabet is function scoped. So we cannot access the variable alphabet outside of a function. So if we try this:
var animal = "cat";
function anyFunction() {
var place = "lagos";
}
console.log(place); // error: place is not defined
We'll get an error because place is not available outside the function. var variables can also be re-declared and updated Let’s see the example below.
var animals = "I like dogs ";
var animals = "I like cats more";
This too:
var animals = "I like dogs";
animals= "I like cats more";
This simply means that we can do this within the same scope and get no error.
Hoisting of var
Hoisting is a JavaScript system in which variables and function declarations are moved to the top of their scope before code is executed. So, if we do this:
console.log (animal);
var animal = "dog"
it is interpreted as:
var animal;
console.log(animal); // animal is undefined
animal = "dog"
This means var variables are hoisted to the top of their scope and initialized with a value of undefined.
Issues with var
Remember when I said there were issues with Var, hence the advent of ES6,; I'll use the example below to explain:
var animal = "a dog";
var numberOfDogs = 8;
if (numberOfDogs > 8) {
var animal = "many dogs";
}
console.log(animal) // "many dogs"
So, since numberOfDogs > 8 returns true, animal is redeclared to "many dogs". Though this is not a problem if you knowingly want animal to be redeclared, it becomes a big issue when you do not realize that a variable animal has already been defined before.
If you have used animal in other parts of your code, you might be shocked at the output you might get. It will most likely cause a lot of bugs in your code. This is why let and const are necessary.
Let
let is now generally accepted and preferred for variable declaration. This is because it comes as an improvement to var declarations. It also solves the issues with var that we just talked about. Let's discuss why this is so.
let is block scoped
Unlike var, let is block scoped. A block is a bunch of code within curly braces {}. Thus, a variable declared in a block with let can only be used within that block. Here’s an example to further explain:
let animal = "cat";
let numberOfCats= 8;
if (numberOfCats > 8) {
let totalAnimal= "many cats";
console.log(totalAnimal);// "many cats"
}
console.log(totalAnimal) // totalAnimal is not defined
We see that using totalAnimal printed outside its block (the curly braces) returns an error. This is because let variables are block-scoped as explained earlier. Unlike var, let can not be re-declared but can be updated.
Let me explain this with an example.
This will work:
let animal = "dog";
animal = "cat";
but this will return an error:
let animal = "dog";
let animal = "cat"; // error: Identifier 'animal' has already been declared
This shows a variable declared with let can be updated within its scope just like var but it cannot be re-declared within its scope, unlike var. But, if the same variable is defined in different scopes, there will be no error:
let animal = "dog";
if (true) {
let animal = "cat";
console.log(animal); // "cat"
}
console.log(animal); // "dog"
Notice there is no error, yes? The reason is because both code snippet are treated as different variables since they have different scopes. This simple difference makes let a better choice than var. When using let, you don't have to worry if you have used a name for a variable before because a variable exists only within its scope.
Additionally, since a variable cannot be declared more than once within a scope, the issue discussed earlier that occurs with var can easily be avoided.
Hoisting of let
Similar to var, let declarations are hoisted to the top. The let keyword is not initialized contrasting to var which is initialized as undefined. This means, if you try to use a let variable before declaration, you'll get a Reference Error.
Now Const
const is short for constant, it maintains constant values when variables are declared with it. const declarations share some similarities with let declarations, let’s see them.
const declarations are block scoped
Same way let declarations can only be accessed within the block they were declared, same way goes for const declarations.
const cannot be updated or re-declared
The value of a variable declared with const will always remain the same within its scope, this is because it cannot be updated or re-declared. So, for example, if we declare a variable with const, we can not do this:
const animal = "dog";
animal = “cat";// error: Assignment to constant variable.
or this:
const animal = "dog";
const animal = "cat";// error: Identifier 'animal’ has already been declared
This tells us that const declaration must be initialized at the time of declaration. This pattern is somewhat different when objects are declared with const. Though a const object cannot be updated, its properties can be updated. Thus, if we declare a const object such as this:
const animal = {
type: "dog",
number: 8
}
while we cannot do this:
animal = {
type: "dog",
number: "eight"
} // error: Assignment to constant variable.
we can do this:
animal.type = "cat";
This will now update the value of animal.type without returning errors.
Hoisting of const
Same way let declarations are hoisted to the top but are not initialized, the same also goes for const declarations.