Introduction
ES6, also called ECMAScript 2015 is an addition to JavaScript syntax and adds some cool features to it. ES6 lets you write less code and do more. It makes our code easy to read and understand.
ES6 features are extensively used in projects these days. All libraries/frameworks like React/Vue require knowledge of ES6 newer syntax and features to work with.
In this guide, we will cover not only ES6 features but will also cover a few uses cases to tell how to use them in React applications.
disclaimer: Its gonna be a long article, you don't need to learn in one go.
1. let and const
Traditionally, the keyword var
is been used to declare variables in JavaScript but ES6 introduced two other keywords let
and const
to declare a variable. There are some issues with var
that let
and const
try to solve.
Let's look into details about let
and const
and compare them with var
.
a. let
and const
are block { }
scoped.
This means let
and const
declared in a block can not be accessed outside of that block, whereas var is function scoped, meaning var
variables can not be accessed outside of the function in which it is declared.
See code snippet below for more clarity.
// Scenario - 1
{
const y = 20;
var z = 30;
console.log(y) // 20
console.log(z) // 30
}
console.log(z); // 30
console.log(y); // Uncaught ReferenceError: y is not defined
// scenario -2
function foo(){
var a = 2;
console.log(a); // 2
}
foo();
console.log(a) //Uncaught ReferenceError: a is not defined"
b. let
and const
can not be redclared in the same scope.
We can not redeclare let
and const
variables in the same scope but var
has no such restrictions.
Redeclaring var will overwrite the older variable's value.
// Var scenario
var x = 10;
console.log(x); // 10
var x = "Twitter";
console.log(x) // Twitter
// Let or const scenario
let y = 20;
let y = "Twitter"; // This line gives Error
NOTE that the above program will not print anything unless you remove the erroneous last line.
c. let
and const
can not be accessed before declaration.
let
and const
reside at a special memory location called the temporal dead zone (TDZ). TDZ ends when the execution reaches the line where they are declared. So, after that line, if let
variable is not initialized with a value, it logs undefined.
console.log(a); // Undefined
var a = 10;
let c;
console.log(c); // undefined
console.log(b); // Error
let b = 20;
I have summarized all features of let
and const
in one image. See the below image.
2. ES6 Classes
ES6 classes were introduced with the intention to make writing programs easy for the developers coming from languages like Java, C++, C#, etc.
I have written a detailed article on Classes in JavaScript. That article covers everything from basics to advanced concepts like-
Constructor Method, Encapsulation, Inheritance, polymorphism, and also Secret about Classes in JS. Check Here.
Give a like to that article if you find it useful.
3. Arrow Functions
Arrow functions syntax lets you write functions in a way that is concise, clean, and easy to read.
Let's write a function to calculate the square of a number and return the result using both a regular function and an arrow function.
function square(num){
return num*num;
}
const arrowSquare = (num) => num * num;
console.log(square(4)); // 16
console.log(arrowSquare(6)); // 36
Notice arrow functions return implicitly, without using a return statement.
In the case of a single parameter, you can drop the parentheses ( )
from the arrow functions syntax. See the code below to understand what does it mean.
const arrowSquare = num => num * num;
console.log(arrowSquare(6)); // 36
What if you want to return multiple line things, like an object? You can do it in two ways, either wrap the object in a ( )
or use an explicit return statement.
const person = (name, age) => ({
name:name,
age:age
});
const person2 = (name, age) => {
return {
name:name,
age:age
}
};
console.log(person("Faheem", 23));
console.log(person2("Raza Rython", 30));
Arrow functions don't have their own this
. It inherits the value of the this
keyword from its parent's scope. For details of how this
works, I highly recommend checking my article here.
4. Destructuring Assignment.
Destructuring assignment syntax is a way to get values from an object or array in a cleaner and concise way.
const person = {
name:"Faheem",
role: "Developer",
address:{
street: "101A",
city: "Delhi"
}
}
// Older way
const name = person.name;
const role = person.role;
const city = person.address.city;
const street = person.address.street;
// Destructuring way
const {name, role} = person;
const {street,city} = person.address;
We can also give a different name to the properties of objects while destructuring. We can give a default value too if needed.
See example below.
const person = {
name:"Faheem",
role: "Developer",
address:{
street: "101A",
}
}
const {street : st, city="City Not defined"} = person.address;
console.log(st, city); // "101A", "City Not defined"
Note city prints the given default value"City Not defined" cause city is not in the address object. Also, we have named street
as st
.
5. Spread, Rest, and Ternary operators.
a. Ternary Operator
The ternary operator is an alternative to if-else conditional statements. It is extensively used in React applications.
Let's look at an example
const num = 10;
console.log(num >= 0 ? "Positive":"Negative"); // "Positive"
One ReactJS scenario
In ReactJS, We show a different piece of UI when data is loading and a different piece of UI when data completes loading.
To check if data is loading or not we use a Boolean variable.
Enough theory? Let's see this in action.
const pageLoader = () => "Loading...."
const UIwithData = () => "Interface with data"
let isloading = true;
console.log(isloading ? pageLoader():UIwithData()) // Loading....
Note that we have used functions pageLoader
and UIwithData
to get what to show on the web page. This is how components in React Works.
Components are basically functions that return some specific user interface.
b. Spread and Rest operator.
The three magical dots ...
are used for both spread and rest operators. They only differ in how they are being used.
In a way, rest syntax is the opposite of spread syntax. Spread syntax "expands" an iterable into its elements, while rest syntax collects multiple elements and "condenses" them into a single element.
Let's look at the spread example first.
// Spread
const arr = [2,4,6,8];
const arrayCopy = [...arr];
const person = {
name:"Faheem",
age: 23
}
const personCopy = {...person}
console.log(arrayCopy); // [2, 4, 6, 8]
console.log(personCopy.name); // "Faheem"
Notice to spread an array we use [ ]
and for object { }
is used.
Now, let's see the rest working.
function sum(...allArgs){
console.log(allArgs) // [3, 4, 5]
const sumofAll = allArgs.reduce((acc,ele) => acc + ele);
return sumofAll;
}
console.log(sum(3,4,5)); // 12
Notice all passed arguments are packed in one variable allArgs
and that becomes an array automatically.
React Scenario (You can skip if you don't want to learn React in near future)
In React there is something called state variable
. They can be of any type, like arrays, objects, strings, etc. These state variables are used to show data to the users.
Suppose we have an array as a state variable that stores users, where every user is an object with some properties.
Further, suppose we want to add a user object to existing users array. array.push(user)
works fine to add an user, right? But there is a problem. Array gets mutated directly.
In React, we need to send an updated array to a function and that function sets the value of the user array. For that, we use spread syntax. Take a look below
let users = [{name:"Faheem", role: "MERN Dev"}]
function setUsers(arr){
users = arr
}
const newUser = {
name:"Vinay",
role: "Flutter Dev"
}
setUsers([...users, newUser]); // it creates a new array with new user appended
console.log(users); // Have two users Now
6. Array Methods -> map, reduce, and filter.
map, reduce, and filter are heavily used in React applications. A deep understanding of these methods can make your way easy in learning React.
I have written a detailed article on these newer methods. Not repeating here. Check my blog to learn these methods. Blog Link .
7. Callback Functions
A function passed as an argument to another function is called a callback if that called function invokes the argument function at a later point in time.
For example, if function, say, foo
is called with an argument function, say, bar
and foo calls the bar then bar is termed as a callback function and foo is called a higher-order function.
function foo(func_bar){
console.log("I'm foo");
func_bar();
}
function bar(){
console.log("I'm bar")
}
foo(bar);
// output
"I'm foo"
"I'm bar"
If you want to learn Higher-order functions in detail, check this blog.
8. String Literals
String literals are a cleaner way to embed the value of variables in a string. String literals use back-ticks
(the key just left of key 1 on your keyboard) instead of double quotes(").
To get the value of the variable the syntax is ${var_name}
.
Let us compare both an older way and a string literal way using an example.
const name = "Jack"
const followers = 60000;
// Older way
let result = "Twitter user " + name + " has " + followers + " Followers.";
console.log(result)
// String Literal way
result = `Twitter user ${name} has ${followers} Followers.`
console.log(result);
//output
"Twitter user Jack has 60000 Followers."
"Twitter user Jack has 60000 Followers."
9. Import/Export Statements.
Every JavaScript file is a module in itself. In React applications, there are multiple components (it's a function actually) written in multiple files. These components can be used in any other file.
To use them, we need to first export them from its file and then import where ever you want to use them.
1. Exports
There are two types of exports
a. Named Export - There can be multiple named exports per module.
Syntax below
export function myFunction() {
console.log("My Function");
}
export let myVariable = Math.sqrt(4);
b. Default Export - There can be only one default export per module.
Syntax below
// In-line exporting
export default function () { ... }
// exporting later
const Header = () => {
// body
}
export default Header
2. Imports
To import a named export, it is mandatory to the same name as it has been exported. But, default export can be imported with any name.
Syntax - import module_Name from file_name
at the top of the file.
// default export
import HeaderFile from './components/Header';
// Named Export
import { myFunction } from './functions';
Summary
- let and const
- ES6 Classes
- Arrow Functions
- Destructuring Assignment.
- Spread, Rest, and Ternary operators.
- Array Methods -> map, reduce, and filter.
- Callback Functions
- String Literals
- Import/Export Statements.
In addition to these, you should learn promises, working with APIs and JSON data.
Thank you for reading this long article. I don't want you to go with doubts in your head. Ask them in the comments if you have got any.
I hope it was a great read for you. If you have any feedback please share it in the comment below. Also, if you find it helpful, please like and hit the follow button on the right top corner.
For a quick response, You can reach me on Twitter.