Hi there folks! Continuing the JavaScript learning from freeCodeCamp, this time we move ahead from the Basic JavaScript and would start with the ES6. ECMAScript 6 or ES6 is the major JS version which introduced a variety of helpful features, released in 2015. Going with this, we will explore those features and how to use them in upcoming posts as well.
This post mainly covers the caveats regarding the variable declaration and how ES6 changes its behaviour. So, let's start without delaying anything.
Difference between var
and let
keywords
The usage of var
had some issues, which we'll come across little by little. However, one potential issue is that variables declared with var
can be overridden without any errors. For e.g.
var myName = Prashant;
var myName = Akash;
console.log(myName); // Akash
As you may see, we've overridden the variable myName
, but JavaScript didn't raise any error. With application with larger source code, we may accidentally overwrite a variable, which we don't intend do. This could lead to unexpected behaviours and difficulties in debugging.
To resolve this, ES6 provides the keyword let
for variable declaration. If we were to use let
instead of var
in the above example, the second initialization would lead to an error.
We can also use the
"use_strict"
to enable the strict mode. This would catch common mistakes and unsafe actions.
For e.g.
"use strict";
x = 3.14; // throws an error because x is not declared
Scope differences between var
and let
keywords
If we go back and try to remember the behaviour of the var
keyword w.r.t scopes, we know that any variable declared with it is global and if declared within a function, it's scope is limited to that function only.
let
behaves in a similar way, but with some extra features. For e.g. when we declare a loop variable using the var
keyword, that becomes global. However, declaring the same, using let
would result in its scope limited to the block of the loop.
Let's see an example
arr = [1, 2, 3, 4];
for (var i = 0; i < arr.length; i++) {
arr[i]++;
}
console.log(i); // returns 4
You may notice that the variable i
is accessible outside the loop. If you were to use it again elsewhere, it'd be using the updated value, which might result in unexpected behaviour. However, with let
, this doesn't happen i.e. the loop variable i
will only be accessible within the loop block and not outside of it.
Let's see another example
function checkScope() {
'use strict';
let i = 'function scope';
if (true) {
let i = 'block scope';
console.log('Block scope i is: ', i);
}
console.log('Function scope i is: ', i);
return i;
}
Before we discuss the output of the above code, a doubt may arise to you. You may ask, that let
should not allow the re-declaration of the variable i
at all. The catch here is that it restricts the same declaration within the same scope. In the above piece of code, the second initialization is within a local scope. Hence let
does not raise any error.
Yes, if you would've tried to initialize it outside of the if
block, it should have a complaint about that. Now, let's move to the output of the above code.
The output of this function would be
Block scope i is: block scope
Function scope i is: function scope
And can you guess which value of i
would be returned? Think!
The answer is function scope
would be returned, as the variable i
within the local scope of if
condition is not visible outside of its block. Hence the global i
is returned.
What if I change the code slightly to this
function checkScope() {
'use strict';
let i = 'function scope';
if (true) {
i = 'block scope';
console.log('Block scope i is: ', i);
}
console.log('Function scope i is: ', i);
return i;
}
What do you think, would be returned now? Before that, did you notice the change? I removed the let
keyword from inside of if
block. That's it. Now, think!
This time, block scope
would be returned. I see you ask why? Well, it's because this time instead of declaring a new variable with the same name in scope, we are instead, overriding the global variable i
. Hence, the changes to it are reflected outside of the function.
Variable declaration using the const
keyword
ES6 not only provides the let
keyword to declare a variable but also a const
keyword to do so. The difference is that the variables declared with const
are read-only. It means that once the variable is declared, it cannot be reassigned. These variable act as a constant value.
It is a common practice to declare constants using the uppercase letters with words separated with underscores.
The use of const
helps us to avoid accidentally changing the constants within a program. An example of its use can be seen as
const PI = 3.14;
PI = 2.17; // throws an error
Mutating arrays declared with const
We should know that objects, arrays or functions would be mutable when assigned to a variable using const
. It is actually the variable identifier, which cannot be reassigned.
Let's see an example for an array
const s = [4, 5, 6, 7];
s = [1, 2, 3]; // throws an error, as assignment to a const variable
s[4] = 8; // this would work fine
console.log(s); // [4, 5, 6, 8]
The thing which is to be noticed here is that the values within the array are mutable. Even though we change the array elements, the variable s
would still point to the same memory location. Only the value to that memory location has been changed.
Yes, if we would try to point s
to some other memory location i.e. some other array or value, it would throw an error.
Preventing object mutation
From the above, we found that const
declaration doesn't actually protect the data from mutation. It only prevents the variable identifier to point to some other location instead.
However, if we want to prevent data mutation within an object, JavaScript provides the function Object.freeze
.
After the object is frozen, any attempt to add, update or delete the properties would be rejected without any error.
function freezeObj() {
let MATH_CONSTANTS = {
PI: 3.14
};
Object.freeze(MATH_CONSTANTS);
MATH_CONSTANTS.PI = 99; // ignored and mutation won't be allowed
return MATH_CONSTANTS.PI;
}
The above would still return 3.14. However, if you'd use the strict mode, it will throw an error.
Conclusion
At the end of this post, we found the major differences between var
, let
and const
keywords and where and why of using them. Further, we found that we can also prevent any data mutation using Object.freeze()
method which comes in handy at times.
References
We'll meet next time with other ES6 features so that we can improve our JS knowledge further. Till then be curious and keep learning. :)
Top comments (0)