Introduction to Modern JavaScript
JavaScript is one of the most popular programming languages in the world. It can be used to build web/ mobile applications, real-time networking applications, command-line tools, etc. In 2015, ECMA release a new version called ECMAScript 6 (ES 6). This specification defined many new features for JavaScript. Let’s see those features in this article.
Declaring variables and constants
Before ES6, the var
keyword is used to declare any kind of variables. But there are multiple issues with this keyword.
- It is not supported for block scope variables. In other words, the variable declared with the
var
keyword is visible throughout the script. So it is difficult to make sure a variable name is not duplicated with the script. - It doesn't have a way to make a final variable or constant.
Instead, ES6 introduced two separate keywords called let and const to manage these difficulties. The let
keyword is used to declare variables and it will be visible within the particular scope/ block in the script.
In this example, I declared two variables using the let
keyword. The sum variable is only visible inside the calculateTotal function. The element variable is only visible within the for loop. This is called the block scope variable. If someone tries to access the sum variable from outside the function, It will throw an error called ‘ReferenceError’.
Another keyword introduced by the ES6 is the const
keyword. It is used to declare constants that should be immutable throughout the script.
So we got an error called ‘TypeError’.
Most of the developers have confusion with the const
keyword when dealing with reference type variables. Because they think the object will be immutable if it is declared as constant. Actually, this variable holds the memory address instead of the object. So, that memory address is immutable. But it doesn't mean you cannot change key-value pairs in the object.
This is a perfectly valid statement.
Object Freeze() and Seal() Methods
In the above example, you see that we can add other properties to the object even if it is declared constant. To overcome it, the freeze() and seal() methods can be used. As the names suggest that both methods are used to create non-extensible objects.
Freeze() method — Property extension and deletion are prevented. It will freeze property values if it is the first level value. In other words, it cannot freeze inner objects.
In the above example, I tried to change four different properties.
- Add new property —not possible
- Remove property — not possible
- Change a property — not possible
- Change inner object property — possible
Seal() method — Property extension and deletion are prevented. But it cannot prevent the changes in property values.
Output,
Arrow Functions
Array functions are a really nice approach to write the same function more shortly and cleanly. It is very useful to pass a call-back function as a method argument.
You can see that arrow functions remove the extra noise in the code. Let’s see the conversion of the normal function to the arrow function.
First, we can replace the fat arrow for the function keyword (step 1: Remove function keyword, put a fat arrow between parameters and code block.). If the code block has only a single line, the curly brackets are not required. If it is a return statement, the return keyword is also removed(step 2).
If the function has only a single parameter, we can remove the parenthesis too.
const printName = name => console.log('Hello, ' + name);
The simplicity is not the only benefit of these arrow functions. Let’s see some benefits from arrow functions.
We all know the this
keyword in regular function is referencing window object(in browsers) or global object(in node). But if we use the this
keyword in an object, it references the current object. Let’s explain it with e proper example.
Calling this keyword in a method of an object.
Output,
You can see the this
keyword is referencing the current object. But it is different in a regular function.
Output,
You can clearly see the this
keyword in a regular function is referencing the global object. So, what will happen a regular function calls this
keyword inside a method of an object.
Here, I pass a regular function as call back function in line 10. So, the this.title
is undefined inside this regular function. Because the function is referencing the global object as this
keyword.
There are several ways to overcome this problem.
let self = this;
First, we need to define the self variable inside the showTags method. Then we can use it instead of this
keyword. There are few other ways like thisArg
argument, bind(this)
method, etc. But these are some all patterns to solve this problem. In modern JavaScript, arrow functions can be used to solve it. Because the arrow functions inherit this
from the containing function.
Output,
So, I think you understand the simplicity of the program by using arrow functions.
Objects in Modern JavaScript
In ECMAScript, the object declaration also has some minor changes. But it will be really useful to simplify the code. Let’s see those changes.
You can see the deliveryTime variable is initialized in line 2. Also, I used the same name for a key of the object in line 8. So, it doesn't have the usual key-value pair. The reason is if we use the same name as the key of an object and another variable, It doesn't need to mention it explicitly.
If the object has dynamic property (key will be changed with the situation), we can use square brackets to wrap up the variable name. In this example, line no 9 has a property called status. It can be changed with the situation like prepareStatus, deliveryStatus, etc.
Template Literals
Before ES6, the escape notations are used to specify new lines, single quotes, etc. It was a little ugly way to create a custom template. The template literals are used to overcome these difficulties. Also, it introduced dynamic properties inside the template.
You can see the line number 1 and line numbers 7 to 13 are the same. But the line number 7 to 13 is the actual format of the text. So, you can easily understand the actual way of the template. I think this will be really nice feature if you work with templates like this.
Classes
Actually, modern JavaScript is more related to object-oriented concepts. If you are from Java, .NET background, you already familiar with OOP concepts. Even though it’s not the same, but still has some similar behaviors. Let’s see the class creation first.
First, you have to use the class
keyword to define the class scope. Then the constructor is created inside the code block. If you know Java, you know that the constructor must have the class name. But here the constructor is created by the constructor
keyword.
Here I created two classes called ‘Student’ and ‘SemesterOneStudent’. Furthermore, the SemesterOneStudent is inherited from Student. So, the studentDetails method is overridden in the sub-class. If you went through the code, you can see a similar code like method override in lines 38 to 40. So, you can easily override methods in JavaScript.
Output,
Spread Operator and Rest Operator
The spread operator is a cool feature in modern JavaScript to take all elements from an array or object. This is very useful to create a clone, combine two arrays/objects, etc. The rest operator has used if a function has a varying number of parameters. Let’s see some examples to understand it.
Output,
As you see these operators are really useful when dealing with arrays and objects.
Promises
As you know JavaScript is an asynchronous programming language. The promises are used to handle this asynchronous behavior. In the real world, promises are some statements that can end up with two different outcomes. When time passes, the promise can be either fulfilled or rejected. But it will take time to accomplished one of them. It will stay ‘pending state’ until it resolves it.
- Pending — The initial state before goes to either fulfilled or rejected.
- Fulfilled — The operation was completed successfully.
- Rejected — The operation failed.
Let’s go through with a proper example to understand it.
The HTTP request takes time to go to the server and send the response back. So, this process should wait until the response back. Therefore, it is wrapped by a promise (Line 5 to 12). Let’s see how to use then, catch, and finally methods.
If the task is resolved successfully, the then
method is called. If not, it calls the catch
method. Anyway, this process ends up either fulfilled or rejected. Finally, this finally
method is called. It's much similar to the Java finally keyword.
There is another way by using async functions and the await keyword. Actually, it was built on top of the promises and it just syntactical sugar in the language that allows us to write asynchronous code in the synchronous pattern. Let’s see how it happens.
So, I know this is not a full explanation of modern JavaScript features. I hope this article is helpful to start learning these cool features. Happy Learning !