JavaScript started as a scripting language in 1996, with all the necessary features for client-side programming. But there was not any major release or changes until 2015.
If you are a javascript developer, then knowing es6 is very important. It will make you more productive and give you some better ways to write code. In this article, we are going to learn about Modern JavaScript with ES6.
What is ES6 anyway?
The ES6 or ECMAScript 2015 is the version of javascript that released the latest syntax features and other major changes. ECMA Script is the standardization of the JavaScript language.
Introduction to new es6 syntax like arrow functions, destructuring, spread operators improved the coding speed and productivity of developers.
New versions of ECMAScript are released every year such as ES6, ES7, ES8, ES9, ES10. However, ES6 is the most major release of javascript and we are going to look at all of its features.
Top ES6 Features
Before diving into the latest es6 features, it is recommended that you have an understanding of basic javascript syntax and its features.
1. Arrow Functions
Arrow functions offer a distinct and unique style of writing functions in javascript. With arrow functions, instead of using the function keyword, the fat arrow sign (=>) is used.
// NORMAL FUNCTION function add(a, b) { return a + b } // ARROW FUNCTION const add = (a, b) => a + b
Arrow functions have a distinct feature that automatically returns the value of the expression after the arrow (=>) sign. Also, the parenthesis can be omitted if it takes only one argument.
If we want the function body to execute multiple lines of code, then we can open braces after the arrow and explicitly return the values.
// Parenthesis are optional for single argument const double = num => 2 * num // Parenthesis are required for 0 or more arguments const log = () => console.log('hello') const multiply = (a, b) => a * b // With a function body, use explicit return const logAndMultiply = (a, b) => { const res = a * b console.log(a, '*', b, '=', res) return res }
Using arrow functions can give you more freedom in the style of writing functions. However, one caveat to remember is that you must define arrow functions beforehand to call it since it is a function expression.
2. Destructuring
Destructuring helps us to pull out the values of an array or an object. This is convenient if you have an array and you want, say 1st and 3rd values. In the case of objects, destructuring helps us to get the desired properties. We can pull out the properties we want by using its name inside the curly bracket syntax.
Here is an example of object de-structuring.
const query = { name: 'John doe', age: 20, email: 'johndoe@gmail.com' } const { name, age } = query console.log(name, age)
And array destructuring:
const users = ['user1', 'user2', 'user3', 'user4'] const [user1, , user3] = users console.log(user1, user3) // user1 user3
We can skip the items using a comma(,) and then destructure the element. Note that in array destructuring, unlike objects, there is no property name, so it is the order of the elements in the array that matters.
Why destructuring?
Destructuring is required because in JS we have to mostly deal with the properties of an object or elements of an array. Array destructuring is not that common but object destructuring is, and the example below shows it.
exports.signUp = catchAsync(async (req, res, next) => { // object destructuring, req.body is an object… const { username, email, password, role, secretKey } = req.body // we would have to do this without destructuring // const username = req.body.username // const email = req.body.email // const password = req.body.password if (!username || !email || !password) { return next( new AppError( 400, `Please pass the required fields` ) ) } }
3. The spread operator
The spread operator in es6 is denoted using three dots or ellipsis (…) and this operator is used to pull out all the values of an object or an array.
const obj = { name: 'test', age: 20 } const extendedObj = { ...obj, email: 'test@gmail.com' } console.log(extendedObj) // { name: 'test', age: 20, email: 'test@gmail.com' }
It will just copy all the values of an object or an array and put it into a new array/object. Note that you cannot spread the values of an object or array outside {} or [] respectively.
You can use the spread operator in the beginning or between or at the end, wherever you want the values to be expanded. The code below shows an example of array destructuring.
const array = [5, 6, 7, 8, 9, 10] const extendedArray = [1, 2, 3, 4, 5, ...array] console.log(extendedArray) // [ // 1, 2, 3, 4, 5, // 5, 6, 7, 8, 9, // 10 // ]
4. The Rest Operator
The interesting thing about the es6 rest operator is that it is exactly similar to the spread operator (…). However, it is used in the function parameter list to group up the parameters into an array. Rest operator is used when a function may take variable arguments and it cannot be determined beforehand.
const add = (a, b, ...others) => { let res = a + b for (let other of others) { res += other } return res } console.log(add(1, 3, 4, 5, 6)) // 19
The example method ‘add()’ above, takes the arguments: a, b, and others. Here ‘a’ and ‘b’ are the minimum arguments that must be provided but the …others become an array inside the function that stores the variable parameters.
So, using a loop we can go through all the properties and operate on them.
5. let and const
Traditional javascript used the keyword ‘var’ to declare variables but now with the introduction of let and const in es6, we can create lexically scoped variables.
Lexically scoped simply means that if you declare a variable using let or const, inside a code block, like ‘if’ or ‘for’ loop, then that variable will only be accessible inside that ‘if’ block or loop. This goes the same for functions too. This is not the case with ‘var’. If you declare a variable with ‘var’ inside an ‘if’ block or a loop, then it will be visible inside the entire function where it is defined.
if (true) { let name = 'johnny' var age = 30 // works fine console.log(name) // johnny } console.log(age) // 30 console.log(name) // throws error: name is not defined
We should use let or const wherever possible to avoid the problems related to scope. This is because using ‘var’ can be the doorway to many bugs in your application and it is hard to debug.
Some techniques for using ES6
Now that you are equipped with the basic knowledge of es6 features. It is enough for most use cases. Let us see some of the usages of es6 to solve specific problems.
1. Swapping values
We can swap two values using destructuring. The trick is to first create an array with the values from variables that we want to swap. Then we just destructure in the order we want.
let a = 5 let b = 10; // use destructuring [a, b] = [b, a]; console.log(a, b); // 10 5
You may say that swapping values is not practical in most cases. Yes, you are right but you can go further to use this technique to rename variables or change the values of multiple variables using more than two variables. Try figuring out how it may work with objects!
2. Currying
We can nest and return functions to make them reusable. The syntax of the arrow functions makes it a one-liner.
// arrow function returning a function const createMultiplier = num => n => n * num const mul5 = createMultiplier(5) console.log(mul5(7)) // 35
The example above shows a function that returns another function. When we call “createMultiplier(5)”, it returns a new function that will now multiply anything with 5. This works because, in javascript, inner functions have access to outer function variables (also called a closure).
This is the essence of currying. It is the technique of breaking down a function that takes many arguments into individual ones to take one or a few arguments. It makes it highly reusable.
Conclusion
This is not the end!
Regularly using ES6 will give you the power of writing a more robust and faster code. There are many more exciting features waiting for you to discover. You should explore ES7, ES8, ES9, ES10, and see what they hold for you, even if they are minor releases!