Demystifying var, let and const in JavaScript

Demystifying var, let and const in JavaScript

Featured on daily.dev

With the release of ES6, two new ways of variable declaration were introduced in JavaScript. These new ways use the keywords ‘let’ and ‘const’. These were basically improvements to the old way of declaring variables using ‘var’. To understand each of these 3 ways of declaring variables, we need to understand two important concepts in JavaScript — Scope and Hoisting. This will further give a better understanding as to why a new way of declaring variables was needed and also the various differences between var, let and const declaration.

Scope

In programming, scope of a variable implies where the variable can be accessed. There is ‘function scope’ and ‘block scope’. Functions scope means that a variable defined inside a function can only be accessed within that function and not anywhere else. A block is a chunk of code enclosed within {}. Any code written within {} is a block. Thus, in block scope, any variable defined within a block will be accessed only inside that block and not anywhere else.

Hoisting

Hoisting is a JavaScript mechanism where variable and function declarations are moved to the top of their scope before code execution.

Screenshot 2020-10-23 at 10.43.15 PM.png

The above code would look suspicious because the variable ‘name’ is being used before it has been declared. But it works fine due to hoisting in JavaScript. JavaScript interprets the above code as follows :

Screenshot 2020-10-23 at 10.47.45 PM.png

Thus, the declaration of the variable ‘name’ is automatically moved to the top of the scope before code execution.

Now, that we have an understanding of scope and hoisting, we can move ahead to discuss var, let and const declarations separately.

var

Variables declared using the ‘var’ keyword have function scope which means that they can be accessed only within the function in which they are declared.

Screenshot 2020-10-23 at 10.53.49 PM.png

The above code will give an error. In the above code, the variable ‘name’ has been declared inside the displayName(). Thus, it can only be accessed inside displayName() and not outside it. But in the above code, we have tried to access it outside the displayName().

Additionally, variables declared using the ‘var’ keyword are hoisted.

Variables using the ‘var’ keyword can be re-declared and updated within their scope.

Screenshot 2020-10-23 at 10.59.41 PM.png

While using ‘var’ keyword to declare variables during hoisting, if a variable is used before declaring, then the variable is assigned a value of ‘undefined’.

Screenshot 2020-10-24 at 2.40.33 AM.png

The output of the above code will be ‘undefined’ because while working with ‘var’ keyword, if hositing occurs, then not only is the variable declaration moved to the top but it is also assigned a value of ‘undefined’. This, however, is not the case with ‘let’ and ‘const’. We’ll see that later in the article.

let

Variables declared using ‘let’ have block scope which means that they will only be accessible inside the block in which they are defined and not outside it.

Screenshot 2020-10-24 at 2.49.49 AM.png

The above code will give the following error : ‘error: Uncaught ReferenceError: second_name is not defined’.

The reason is quite obvious. We are trying to access the variable ‘second_name’ from outside the block in which it has been defined.

Additionally, variables declared using ‘let’ can be updated but not re-declared within their scope.

Screenshot 2020-10-24 at 2.55.15 AM.png

Re-declaring variables will give the following error : error: unknown: Identifier ‘designation’ has already been declared

NOTE : Re-declaration is not allowed within the scope. But outside the scope, re-declaration is allowed because then the re-declared variable is treated as a separate new variable.

Screenshot 2020-10-24 at 3.02.23 AM.png

The output of the above code will be :

Screenshot 2020-10-24 at 3.03.39 AM.png

This is because the variable ‘salary’ defined inside the ‘if’ block is treated as a different variable and it’s scope is limited to the ‘if’ block.

Hoisting takes place with ‘let’ keyword too.

While using ‘let’ keyword to declare variables, during hoisting, if a variable is used before declaration then it is not assigned a value of ‘undefined’ like it used to happen with ‘var’ keyword.

Screenshot 2020-10-24 at 3.08.09 AM.png

The above code will give the following error : error: Uncaught ReferenceError: Cannot access ‘season’ before initialization

This is because, even though the decalration of the variable ‘season’ moves to the top of the scope, it is still not assigned any value.

const

Variables declared using the ‘const’ keyword have block scope just like ‘let’.

Variables declared using ‘const’ can neither be updated nor re-declared. It is therefore recommended to assign a value to the variable during declaration itself(initialisation). For example : const age = 22;

Hoisting takes place with the ‘const’ keyword too. It follows the same rule as ‘let’ that when variable declarations are moved to the top of the scope while hoisting, they are not assigned an ‘undefined’ value.