ECMAScript 2015 or ES2015 is a significant update to JavaScript programming language. It is the first major update to the language since ES5 which was standardized in 2009. Therefore, ES2015 is often called ES6.
What we'll be covering today
- Const, let and var
- Default Arguments
- Arrow Functions
- Template literals
- Map, Reduce and Filter
- Array and Object Destructuring
- Iterables and Loopings
- Rest and Spread Operator
- Object Literals
- Classes in ES6s
- Promises
- Async and Await
- "new" and "this" keyword
1. Const, let and var
1.1 CONST
- Const defines a constant variable which can't be changed throught the code.
- Declaring a variable with const is similar to let when it comes to Block Scope.
For example
const x = 100;
/*
Re-Initializing The Variable.
This will throw an error, as CONST variable can't be changed
*/
x = 200;
/*
Here 'y' variable is defined in a block.
It can't be accessed outside the scope of this block.
The output of this block would be :
1
*/
{
const y = 1;
console.log(y);
}
/*
Will throw an error, CONST y is undefined
*/
console.log(y);
1.2 LET
- "let" defines a variable which can be changed anywhere throught the code.
- It can be re-initialised but not re-declared in the same scope.
- It has a block scope.
let x = 100;
/*
Re-Initializing The Variable.
This will update the value of x to 200
*/
x = 200;
/*
Re-Initializing The Variable in different scopes.
*/
{
let x = 200;
}
/*
Will display 100 as output
*/
console.log(x);
1.3 Var
- Var keyword is an old method for declaring variables in javascript.
- Value of variables declared with var can be changed at any point, during runtime.
- Var has only a global scope.
- MDN recommends to not to use
var
keyword after release oflet
andconst
in ES6.
var x = 10;
for (var i = 0; i < 5; i++) {
var x = 20;
console.log(x); //Returns 20
}
console.log(x); // Returns 20
2. Default Arguments
Default argument or default parameter allows you to set a default value for your function parameter/argument if no value is passed for the same.
Default Argument with ES5
function product(x, y) {
return x * y;
}
/*
Let's just call the function without passing any argument
Output would be : NaN
*/
product();
Handling Default Argument with ES5
function product(x, y) {
const x = typeof x !== "undefined" ? x : 1;
const y = typeof y !== "undefined" ? y : 1;
return x * y;
}
/*
Since we're handling
*/
product();
In a case when no parameter is passed, we have to explicitly handle the error by setting default values of a & b. This doesn't look like a good way of handling default arguments.
Handling Default Argument with ES6
function add(a = 5, b = 10) {
return a + b;
}
add(); // a=5, b=10, sum = 15;
add(2, 3); // a=2, b=3, sum = 5;
add(4); // a=4, b=10, sum=14 ;
Default value of A and B will be only used when no parameter is passed.
3. Arrow Functions
An arrow function is a syntactically compact alternative to a regular function expression without its own binding to this
, super
,
Regular Functions (ES5)
function multiply(x, y) {
return x * y;
}
multiply(10, 4);
Arrow Functions (ES6)
// Example 1
const multiply = (x, y) => {
return x * y;
};
multiply(10, 4);
4. Template Literals
Template literals can contain placeholders. These are indicated by the dollar sign and curly braces. The expressions in the placeholders and the text between the backticks (``) get passed to a function. They are used to concatenate the parts into a single string.
Let's see an example on formatting strings in ES5.
`js
# STRING FORMATTING (WITHOUT ES6)
function welcome(name){
const greetings = 'Hello, ' + name + ' What''s up?';
return greetings;
}
greet('Ishan');
/*
Will display output as :
Hello, Ishan What's up?
*/
`
`js
# STRING FORMATTING (WITH ES6)
function welcome(name){
const greetings = `Hello, ${name} What's up?`;
return greetings;
}
greet('Ishan');
/*
Will display output as :
Hello, Ishan What's up?
*/
`
You might be able to clearly reciprocate the main benefits of the latter approach.
RECAP
- Template Literals are enclosed by back tick(``) instead of single or double quote.
- Placeholders can be inserted between template literals. These are indicated by the dollar sign and curly braces.
5. Map, Reduce and Filter
Map, reduce, and filter are all array methods which were introduced in ES6. Each one will iterate over an array and perform a transformation or computation. Each will return a new array based on the result of the function.
Map Method
The map()
method is used for creating a new array from an existing one, while passing each element of the array to a function.
For example: Let's say we have a people array that contains multiple persons as object. But, we just need the age of each person.
How can we do that? Here's one
const people = [
{ name: "Ishan", age: 19, profession: "Developer" },
{ name: "Rohit", age: 20, profession: "Student" },
{ name: "Bhavesh", age: 18, profession: "Enterprenuer" },
];
const ages = people.map((person) => person.username);
console.log(ages); // [ 19, 20, 18 ]
Filter Method
Filter method take a function parameter which applies on each array element, then whichever element satisfies the parameter condition returns in the new array.
For example: Let's consider that in the above people example, I only want to filter those users, who have an age of greater than 18 years.
const people = [
{ name: "Ishan", age: 19, profession: "Developer" },
{ name: "Rohit", age: 20, profession: "Student" },
{ name: "Bhavesh", age: 18, profession: "Enterprenuer" },
];
const aboveEighteen = people.filter((person) => person.age > 18);
console.log(aboveEighteen);
/* [{ name: "Ishan", age: 19, profession: "Developer" },
{ name: "Rohit", age: 20, profession: "Student" } ] */
Reduce Method
The reduce() method reduces an array of values down to just one value. To get the output value, it runs a reducer function on each element of the array.
For example : Let's say we just want to find the sum of all numbers in an array
const numbers = [1, 2, 3, 4, 5, 6, 7];
// Here prevSum will contain the total sum, upto the previous iterated number.
const sum = numbers.reduce(function (prevSum, num) {
return prevSum + num;
}, 0);
// Here '0' indicates the initial value of sum, before reducer function is exectued.
console.log(sum); // 28
6. Array and Object Destructuring
Destructuring in JavaScript is a simplified method of extracting multiple properties from an array by taking the structure and deconstructing it down into its own constituent parts. It helps in improving the readability and performance of our code.
Destructuring in ES5
// Object Destructuring
var person = {
name : 'Ishan',
age : 19',
profession : 'Developer'
}
const name = person.name; // Deepak
const age = person.age; // dipakkr
const profession = person.profession // 12345
// Array Destructuring
const days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday","Sunday"];
const day1 = days[0];
const day2 = days[1];
const day3 = days[2];
Destructuring in ES6
// Object Destructuring
var person = {
name : 'Ishan',
age : 19',
profession : 'Developer'
}
const { name, age, profession } = person;
console.log(name);
console.log(age);
console.log(profession);
// Array Destructing
const days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday","Sunday"];
const [day1, day2, day3] = days;
console.log(day1); // Monday
console.log(day2); // Tuesday
console.log(day3); // Wednesday
7. Iterables and Iterators
ES6 introduced a new way to interact with JavaScript data structures — iteration. Here is the list of interable data types in JavaScript.
Iterable | Description |
---|---|
Array | We can access each individual element by iterating over an array. |
Map | We can iterate over the key-value pair in a list/array. |
Strings | Strings are both iterable & array like, so we can access each character |
Sets | Collections of values that we can iterate through elements |
Please note that plain objects are not iterable.
for...of
is a new feature in ES6 that can be helpful in accessing the interables element more easily. The for...of statement simply creates a loop iterating over iterable objects. For example,
Iterating using for...of
const array = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20];
for (var item of array) {
console.log(item);
}
Iterating without using for...of
const array = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20];
for (var item in array) {
console.log(array[item]);
}
As clearly depicted above, in the latter case we can access interable elements directly with for...of method more easily.
8. Spread and Rest Operator
Spread and Rest Operators are denoted by ...
three dots. These three dots can either be used as Rest Parameter
or Spread Operator
.
Rest Parameter
It simply collects all the remaning arguments into an array and pass them one by one. Hence, allowing a function to be called with any number of arguments, no matter how it is defined.
Without Using Rest Parameter
// Function to print sum of numbers.
function addition() {
var sum = 0;
for (var i = 0; i < arguments.length; i++) {
sum = sum + arguments[i];
}
return sum;
}
console.log(addition(1, 2, 3, 4, 5, 6, 7, 8, 9)); // 45
Here arguments
is a special array-like object that contains all arguments by their index.
Using Rest Paramter
function addition(...numbers) {
let sum = 0;
for (let i of numbers) {
sum += i;
}
return sum;
}
console.log(addition(1, 2, 3, 4, 5, 6, 7, 8, 9)); // 45
Spread Operator
- Using the spread operator, we can expand array/object/string into a single list or other element.
- Spread operator is exactly the reverse of Rest operator, instead of collecting arguments into an array, it expands an array's elements.
For example
/*
Let's say we want to find the maximum number in two arrays using the
inbuilt Math.max() function
Note that Math.max() function expects a list of numeric arguments, not a single array.
*/
let arr1 = [1, -2, 3, 4];
let arr2 = [8, 3, -8, 1];
alert(Math.max(...arr1, ...arr2)); // 8
9. Object Literals
Object literals are used to create an object in javascript.
- Object can be initialised by directly using the variable name. See Example 1 below.
- Object's method in ES5 require
function
statement. This is no longer required in ES6, you can directly return statement. See Example 2 below. - Object literals key in ES6 can be dynamic. Any Express can be used to create a key.
Let's see object literals in action, through an example.
Object Literals with ES6
const username = "ishandeveloper";
const name = "Ishan";
const password = "SecretNuclearLaunchCode";
const githubID = "https://github.com/ishandeveloper";
const person = {
username,
name,
password,
githubID,
};
console.log(person.username);
console.log(person.githubID);
10. Classes in ES6
Classes support prototype-based inheritance, constructors, super calls, instance and static methods
There are two ways to define classes in JavaScript.
- Class Declaration
- Class Expression
Class Declaration
In order to define class using-declaration method you need to use class
keyword followed by className. The class name must start with Capital letter.
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
Class Expression
Class expression is another way to define a class. Class expressions can be named or unnamed. The name given to a named class expression is local to the class's body.
let Rectangle = class {
constructor(height, width) {
this.height = height;
this.width = width;
}
};
console.log(Rectangle.name);
11. Promises
For supporting asynchronous programming, JavaScript uses a callback. However, the callback implementation has a major problem which is called as Callback hell.
Promises come to rescue to solve the problem of callback hell.
Promises are a pattern that greatly simplifies asynchronous programming by making the code look synchronous and avoid problems associated with callbacks.
A Promise has three states.
- pending: Initial state, neither fulfilled nor rejected.
- fulfilled: It means that the operation completed successfully.
- rejected: It means that the operation failed.
let promise = new Promise(function (resolve, reject) {
setTimeout(() => resolve("Success ! "), 2000);
});
promise
.then(function (result) {
console.log(result);
})
.catch(function (error) {
console.log(error);
});
/*
Result
Success !
*/
DISCLAIMER : Some of the examples and explanations above are inspired from different sources, and rephrased to some extent in my own words, that help me understand the concepts better, all the credit belongs to the respective authors.
Originally published on my personal blog.
Top comments (1)
I think you didn't do the Iterators/Iterables/Generators justice, missing out on function* and yield, the difference between async and sync iterators (the former can yield promises), the simple patterns behind the semantic sugar, why Symbol was required to create them and why they are a prerequisite for rxjs and (to come later) native observables.