Over the past few years, there have been many updates to the JavaScript language. And these updates are very useful if you want to improve your coding.
Keeping abreast of the newest developments in the language is really important. It can help you get a higher paying job, keep up to date with the latest trends, improve your code quality, and excel in your current job.
And you definitely need to know these latest features if you're trying to learn a JavaScript library like React or framework like Angular or Vue.
Recently, there have been many useful additions to JavaScript like the Nullish coalescing operator, optional chaining, Promises, async/await, ES6 destructuring, and more.
So today, we will look at some of these concepts which every JavaScript developer should be aware of.
Let's get started and dive into the things you need to know about JS.
Check out my Mastering Modern JavaScript book to learn all ES6+ features in detail. This book covers all the pre-requisites for learning React and helps you to become better at JavaScript and React.
Let and const
Before ES6 came, JavaScript was using var
keyword so JavaScript was only having a function and global scope. There was no block-level scope.
With the addition of let
and const
JavaScript has added block scoping.
using let:
When we declare a variable using let
keyword, we can assign a new value to that variable later but we cannot re-declare it with the same name.
// ES5 Code
var value = 10;
console.log(value); // 10
var value = "hello";
console.log(value); // hello
var value = 30;
console.log(value); // 30
As can be seen above, we have re-declared the variable value
using var
keyword multiple times.
Before ES6, we were able to re-declare a variable that is already declared before which was not having any meaningful use, instead, it was causing confusion.
If we already have a variable declared with the same name somewhere else and we're re-declaring it without knowing we already have that variable then we might override the variable value causing some difficult to debug issues.
So when using let
keyword, you will get an error when you try to re-declare the variable with the same name which is a good thing.
// ES6 Code
let value = 10;
console.log(value); // 10
let value = "hello"; // Uncaught SyntaxError: Identifier 'value' has already been declared
But, the following code is valid
// ES6 Code
let value = 10;
console.log(value); // 10
value = "hello";
console.log(value); // hello
We don't get an error in the above code because we're re-assigning a new value to the value
variable but we're not re-declaring value
again.
Now, take a look at the below code:
// ES5 Code
var isValid = true;
if(isValid) {
var number = 10;
console.log('inside:', number); // inside: 10
}
console.log('outside:', number); // outside: 10
As you can see in the above code when we declare a variable with var
keyword, it's available outside the if
block also.
// ES6 Code
let isValid = true;
if(isValid) {
let number = 10;
console.log('inside:', number); // inside: 10
}
console.log('outside:', number); // Uncaught ReferenceError: number is not defined
As you can see in the above code, the number
variable when declared using let
keyword is only accessible inside the if block and outside the block it's not available so we got a reference error when we tried to access it outside the if block.
But if there was a number
variable outside the if block, then it will work as shown below:
// ES6 Code
let isValid = true;
let number = 20;
if(isValid) {
let number = 10;
console.log('inside:', number); // inside: 10
}
console.log('outside:', number); // outside: 20
Here, we have two number
variables in a separate scope. So outside the if block, the value of number
will be 20.
Take a look at the below code:
// ES5 Code
for(var i = 0; i < 10; i++){
console.log(i);
}
console.log('outside:', i); // 10
When using the var
keyword, i
was available even outside the for
loop.
// ES6 Code
for(let i = 0; i < 10; i++){
console.log(i);
}
console.log('outside:', i); // Uncaught ReferenceError: i is not defined
But when using let
keyword, it's not available outside the loop.
So as can be seen from the above code samples, using let
keyword makes the variable available only inside that block and it's not accessible outside the block.
We can also create a block by a pair of curly brackets like this:
let i = 10;
{
let i = 20;
console.log('inside:', i); // inside: 20
i = 30;
console.log('i again:', i); // i again: 30
}
console.log('outside:', i); // outside: 10
If you remember, I said we cannot re-declare a let
based variable in the same block but we can re-declare it in another block. As can be seen in the above code, we have re-declared i
and assigned a new value of 20
inside the block and once declared, that variable value will be available only in that block.
Outside the block when we printed that variable, we got 10
instead of the previously assigned value of 30
because outside the block, the inside i
variable does not exist.
If we don't have the variable i
declared outside, then we'll get an error as can be seen in the below code:
{
let i = 20;
console.log('inside:', i); // inside: 20
i = 30;
console.log('i again:', i); // i again: 30
}
console.log('outside:', i); // Uncaught ReferenceError: i is not defined
using const:
const
keyword works exactly the same as the let
keyword in block scoping functionality. So let's look at how they differ from each other.
When we declare a variable as const
, it's considered a constant variable whose value will never change.
In the case of let
we're able to assign a new value to that variable later like this:
let number = 10;
number = 20;
console.log(number); // 20
But we can't do that in case of const
const number = 10;
number = 20; // Uncaught TypeError: Assignment to constant variable.
We even can't re-declare a const
variable.
const number = 20;
console.log(number); // 20
const number = 10; // Uncaught SyntaxError: Identifier 'number' has already been declared
Now, take a look at the below code:
const arr = [1, 2, 3, 4];
arr.push(5);
console.log(arr); // [1, 2, 3, 4, 5]
We said const
variable is constant whose value will never change but we have changed the constant array above. So isn't it contrary?
No. Arrays are reference types and not primitive types in JavaScript
So what actually gets stored in arr
is not the actual array but only the reference(address) of the memory location where the actual array is stored.
So by doing arr.push(5);
we're not actually changing the reference where the arr
points to but we're changing the values stored at that reference.
The same is the case with objects:
const obj = {
name: 'David',
age: 30
};
obj.age = 40;
console.log(obj); // { name: 'David', age: 40 }
Here, also we're not changing the reference of where the obj
points to but we're changing the values stored at that reference. So the above code will work but the below code will not work.
const obj = { name: 'David', age: 30 };
const obj1 = { name: 'Mike', age: 40 };
obj = obj1; // Uncaught TypeError: Assignment to constant variable.
The above code does not work because we're trying to change the reference that the const
variable points to.
So the key point to remember when using
const
is that, when we declare a variable as a constant usingconst
we cannot re-define and we cannot re-assign that variable but we can change the values stored at that location if the variable is of reference type.
So the below code is invalid because we're re-assigning a new value to it.
const arr = [1, 2, 3, 4];
arr = [10, 20, 30]; // Uncaught TypeError: Assignment to constant variable.
But note that, we can change the values inside the array, as seen previously.
The following code of re-defining a const
variable is also invalid.
const name = "David";
const name = "Raj"; // Uncaught SyntaxError: Identifier 'name' has already been declared