A complete, simple, easy to use cheat sheet for ES6-ES10.
Support us at:
- Website: http://devsocial.io/
- YouTube: Devsocial
- Define variables (const & let)
- Template Strings
- String.padStart() / String.padEnd()
- Arrow function
- Spread Operator
- Rest Operator
- Default Parameter
- Array Destructuring
- New Useful Array Methods
- Object Destructuring
- Object Enhancements
- New Useful Object Methods
- For ... of Loop
- Class
- Import/Export
- Hash map
- Sets
- Generator
- Handling Errors (try/catch/throw/finally)
- Promise
- Async/await
Define a constant variable:
const variableName = "value"
Constant variables can not be changed or reassign or redefine:
const variableName = "other value"
//-->SyntaxError
variableName = "other value"
//-->SyntaxError
You can change, add value to a constant array but you cannot reassign or redefine it:
const arrayName = [1,2,3,4]
arrayName.push(5)
//-->[1,2,3,4,5]
const arrayName = [9,8,7,6]
//-->SyntaxError
You can change, add value to a constant object but you cannot reassign or redefine it:
const person = {name:"DevSocial",email:"[email protected]",city:"L.A"}
person.name ="OtherName" //change a property
person.location = "U.S" //add a new property
person = {name:"Daniel",email:"[email protected]",city:"L.A"} //reassign it
//-->SyntaxError
Constant variables exist in a block scope:
var x = 1
{ //this is a block scope
const x = 2
}
console.log(x)
//-->1
Define a let variable:
let variableName = "value"
let variables exist in a block scope:
var x = 1
{ //this is a block scope
let x = 2
}
console.log(x) //-->1
let variables cannot be redefined, but can be reassigned:
let variableName = "other value"
//-->SyntaxError
variableName = "other value"
Variable defined by var
get hoisted at the top
console.log(sayHello)
//-->undefined
//variable sayHello is hoisted at the top before it was defined by var
//This means that variable is there but with value of undefined
var sayHello = "HelloWorld"
console.log(sayHello)
//-->"HelloWorld"
Variable defined by let
doesn't get hoisted at the top
console.log(sayHello)
//-->ReferenceError:sayHello is not defined
let sayHello = "HelloWorld"
console.log(sayHello)
//-->"HelloWorld"
let
should be used in for
loop instead of var
because variables defined by var
will be leaked outside the for
loop and will only reference the ending result of i
if there is a setTimeout
function:
//with var
for (var i = 0; i < 3; i ) {
console.log(i);
setTimeout(function(){
console.log("The number is " i);
}, 1000);
};
//after 1 sec
//-->The number is 2 (x3)
//setTimeout reference i after when the for loop ends
console.log(i)
//--> 2
//i is leaked outside the for loop
//with let
for (let i = 0; i < 3; i ) {
setTimeout(function(){
console.log("The number is " i);
}, 1000);
}
//after 1 sec
//-->The number is 0
//-->The number is 1
//-->The number is 2
Template string is a quick way for you to handle a string.
You can reference variables:
let first = "Dev";
let last = "Social";
console.log(`Hello ${first}${last}`);
//--> "Hello DevSocial"
You can use expression (i.e adding numbers):
//More practical example
let num1 = 2;
let num2 = 3;
console.log(`The number is ${num1 num2}`);
//--> "The number is 5"
You can just break a line, use tab without using \n
\t
:
console.log(`Hello
World`)
//-->"Hello
//World"
//More practical example
let channel_name = "desocial";
let base_url = "https://www.youtube.com/"
let url = `${base_url}channel/${channel_name}/`
//-->"https://www.youtube.com/channel/desocial"
.padStart(), .padEnd() are used to fill up a string to a certain number of characters
.padStart()
.padStart() will add a certain number of characters at the beginning of a string to fill up the required string length.
let maxlength = 15;
let string = "DevSocial"
console.log(string.padStart(maxlength,"a"))
//-->"aaaaaaDevSocial"
.padEnd()
.padEnd() will add a certain number of character at the end of a string to fill up the required string length.
let maxlength = 15;
let string = "DevSocial"
console.log(string.padEnd(maxlength,"a"))
//-->"DevSocialaaaaaa"
Arrow function is a new way of defining a function for cleaner code and is commonly used in callback function
Define an arrow function with return
:
let functionName = (param1,param2) => {
sum = param1 param2;
return sum;
}
Define an arrow function without return
:
let functionName = (param1, param2) => (param1 param2) ;
If there is no parameter, you can just use parentheses:
let functionName = () => ("Hello world");
//Same way before ES6
function functionName(param1,param2){
return param1 param2;
}
Arrow function is commonly used in callback:
let myArr = [1,2,3]
let doubleThenFilter = arr => arr.map((value) => (value * 2) )
.filter((value) => (value % 3 === 0));
doubleThenFilter(myArr)
//Same way before ES6
function doubleThenFilter(arr){
return arr.map(function(value){
return value *2;
}).filter(function(value){
return value % 3 === 0;
})
};
A spread operator would break down an array into values so that they can be easily used:
let nums = [4,5,6];
let nums2 = [1,2,3,...nums,7,8];
console.log(nums2);
//--> [1,2,3,4,5,6,7,8]
Spread operator is commonly used when a function doesn’t accept an array as a parameter:
function sumValues(a,b,c){
console.log(arguments); //print out an array of the arguments of the function
return a b c;
}
let nums = [2,3,4];
sumValues(...nums); //values 2,3,4 of nums array has been passed to a,b,c parameters
//-->[2,3,4]
//-->9
sumValues(5,5,...nums); //value 2 of nums array has been passed to c parameter
//-->[5,5,2,3,4]
//-->12
//Another example
let nums = [1,2,3,4];
Math.min(nums);
//--> NaN
Math.min(...nums);
//-->1
Rest operator is commonly used in a function when you don’t know the number of input arguments passed into the function:
function printRest(a,b,...args){
console.log(a);
console.log(b);
console.log(args); //args is the array of arguments
console.log(...args); //...args are values that has been broken down
}
//args is just a name, you can name it with anything
printRest(1,2,3,4,5);
//-->1
//-->2
//-->[3,4,5]
//-->3 4 5
function smallest(...args){
return "Smallest number is " Math.min(...args);
}
smallest(1,2,3,4,5);
//--> "Smallest number is 1"
Set default value to the parameter:
//without default parameter
function sum(nums) {
let total = 0;
nums.forEach((d)=>(total =d));
return total;
};
sum();
//-->TypeError
//with default parameter
function sum(nums =[]) {
let total = 0;
nums.forEach((d)=>(total =d));
return total;
};
sum();
//-->0
Assign values from an array to different variables:
var arr = [1,2,3];
var [a,b,c] = arr;
console.log(a); //-->1
console.log(b); //-->2
console.log(c); //-->3
The new array methods that would come in handy in ES6,7,8,9.
Array.from
(Not yet supported by Edge)
Convert array-like-object into an array. An array-like-object is an object but looks like an array.
let myDivs = document.querySelector("div"); //This will return an array-like-object
let mySet = new Set([1,1,2,2,3,3]); //Set is also an array-like object
let arrConvert = Array.from(mySet);
//--> [1,2,3]
.includes()
Check if an item exist in an array, return Boolean:
let myArr = [1,2,3,4,5];
console.log(myArr.includes(2));
//-->true
.flat()
(Not yet supported by Edge)
Flatten a nested array, remove empty spots; then return a new array:
let myArr = [1,2,,[3,4]];
myArr.flat();
//-->[1,2,3,4]
let myArr2 = [1,2,[3,4,[5,6]]];
myArr2.flat();
//-->[1,2,3,4,[5,6]];
You can assign the depth level of .flat()
:
let myArr2 = [1,2,[3,4,[5,6]]];
myArr2.flat(2);
//-->[1,2,3,4,5,6];
myArr2.flat(Infinity); //Infinity would flatten until there's no nested array
//-->[1,2,3,4,5,6]
.flatMap()
(Not yet supported by Edge)
An upgrade version of .map()
in the case that .map()
return a nested array, .flatMap()
would flatten it:
let myArr = [1, 2, 3, 4];
myArr.map(x => [x * 2]);
// [[2], [4], [6], [8]]
myArr.flatMap(x => [x * 2]);
// [2, 4, 6, 8]
//A more practicle example
let myArr= ["Javascript is fun", "and", "ES2019 is also fun"];
myArr.map(x => x.split(" "));
// [["Javascript","is","fun"],["and"],["ES2019", "is", "also", "fun"]]
myArr.flatMap(x => x.split(" "));
// ["Javascript", "is", "fun", "and", "ES2019", "is", "also", "fun"]
Define and assign value to variables with the same names as properties:
const person = {
first:"Dev",
last: "Social",
}
//define and assign value to variables with the same name as properties in the object
let { first, last } = person;
console.log(first)
//-->"Dev"
console.log(last)
//-->"Social"
Define and assign value to variables with different names from properties:
const person = {
first:"Dev",
last: "Social",
}
//define and assign values to variables with different names from properties in the object
let { first:differentFirst, last:differentLast} = person;
console.log(differentFirst)
//-->"Dev"
console.log(differentLast)
//-->"Social"
Define and assign value to variables and exclude unwanted variables using spread operator:
const person = {
first:"Dev",
last:"Social",
city:"L.A",
state:"CA",
country:"USA",
};
const { state, ...personWithoutState } = person;
console.log(state);
//-->"CA"
console.log(personWithoutState);
//-->{first: "Dev", last: "Social", city: "L.A", country: "USA"}
You can assign default parameter value as a destructured object
function createPerson({
name = {
first:"Javascript",
last: "ES6",
},
isFun = false,
} = {}){ //an empty object need to be assigned to the destructured object
return [name.first, name.last, isFun];
}
createPerson();
//-->["Javascript", "ES6", false]
createPerson({ isFun:true });
//-->["Javascript", "ES6", true]
createPerson({name:{ first: "Dev", last:"Social"}});
//--> ["Dev", “Social”, false]
The new object methods that would come in handy in ES6,7,8,9.
Object.assign()
Object.assign()
is commonly used to properly clone an object, since you just cannot simply clone an obj by assign the object equal to another object.
//NOT A WAY OF CLONING AN OBJECT
let obj1 = {name:"DevSocial"};
let obj2 = obj1; // this will not clone obj1, but only assign a reference to obj1
obj2.name = "some text";
console.log(obj1.name);
//-->"some text"
//BETTER WAY OF CLONING AN OBJECT
let obj1 = {name:"DevSocial"};
let obj2 = Object.assign({},obj1);
obj2.name = "some text";
console.log(obj1.name);
//-->"DevSocial"
Object.assign()
however is not a deep clone. If the object's property holds a value of an array, that array still have a reference in the cloned object:
//NOT A DEEP CLONE
let obj1 = {myArr:[1,2,3]};
let obj2 = Object.assign({},obj1);
obj2.myArr.push(4)
console.log(obj1.myArr);
//-->[1,2,3,4]
.entries() / .fromEntries()
.entries()
would convert the key:value pairs of an object into an array that holds [key,value] pairs.
const myObj = {
key1: "value1",
key2: "value2",
key3: "value3",
};
const entries = Object.entries(myObj);
console.log(entries);
//--> [["key1","value1"],["key2","value2"],["key3","value3"]]
.fromEntries()
would convert [key,value] pairs of an array into key:value pairs of an object :
const myObj2 = Object.fromEntries(entries);
console.log(myObj2);
//--> {key1:"value1", key2:"value2", key3:"value3"}
You can set a property of an object with the value of a variable:
let somevar = "firstName";
let person = {
[somevar]: "Dev"
};
console.log(person);
//-->{firstname:"Dev"}
You can shorten the object methods inside an object:
//ES6 and above
let myObj ={
sayHello(){
console.log("Hello World");
}
}
//Before ES6
var myObj ={
sayHello: function(){
console.log("Hello World");
}
}
A for
of
loop introduce a simpler way to iterate the values of a iterable object (a string, an array, a set, a map, a generator, or a DOM collection).
let myArr =[1,2,3];
for (let num of myArr){
console.log(num)
}
//-->1
//-->2
//-->3
let myStr = "Hello"
for (let ch of myStr){
console.log(ch)
}
for
of
is only designed for iterating the value of an iterable object, not for updating it:
let myArr =[1,2,3];
for (let num of myArr){
num =1;
};
console.log(myArr);
//-->[1,2,3]
// myArr was not updated
// If you want to update it, you need to use a temporary object to store the value
let tempArr = [];
for (let num of myArr){
num =1;
tempArr.push(num);
};
myArr = tempArr;
console.log(myArr);
//-->[2,3,4]
More about iteration with other iterable objects can be found at: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of
Class in ES6 or above is a combination of constructor functions and prototypes in ES5 that make Object Oriented Programing in Javascript more clean and readable
class
will define a constant and class
does not hoist.
Define a class
object. this class
will replace constructor function and prototypes in ES5:
//ES6 and above
class Person {
constructor(firstName, lastName, favoriteNum){
this.firstName = firstName;
this.lastName = lastName;
this.favoriteNum = favoriteNum;
}
multiplyFavoriteNum(num){
return num * this.favoriteNum;
}
};
let newPerson = new Person("Dev","Social",7);
newPerson.multiplyFavoriteNum(10) ;
//-->70
//Same way before ES6
function Person(firstName, lastName, favoriteNum) { //this is a constructor function
this.firstName = firstName;
this.lastName = lastName;
this.favoriteNum = favoriteNum;
}
Person.prototype.multiplyFavoriteNum = function(num){
return num*this.favoriteNum;
}
var newPerson = new Person("Dev","Social",7);
newPerson.multiplyFavoriteNum(10) ;
//-->70
Static
is a function that only accessed by the class
object. Other objects that are created from class object cannot access static
:
class Person {
constructor(firstName,lastName,favoriteNumber){
this.firstName = firstName;
this.lastName = lastName;
this.favoriteNum = favoriteNum;
}
multiplyFavoriteNum(num){
return num * this.favoriteNum;
}
static callStatic(){
return "static has been called"
}
};
var newPerson = new Person("Dev","Social","blue",7);
newPerson.callStatic();
//-->ERROR
Person.callStatic() ;
//-->"static has bene called"
A class can inherit anotther class using extends
key word and super
keyword:
class Vehicle{
constructor(make,model,year){
this.make=make;
this.model=model;
this.year=year;
}
start(){
return `${this.make} ${this.model} ENGINE START`;
}
};
class Car extends Vehicle{
constructor(make,model,year,numWheels){
super(make,model,year); //inherit make,model,year from Vehicle
this.numWheels = 4;
}
};
var newCar = new Car("Honda","Civic",2019);
newCar.numWheels;
//-->4
newCar.start();
//-->"Honda Civic ENGINE START"
Named export: You can export an object or objects in a .js file and then import that object to another .js file:
file1.js:
export sayHello = "HelloWorld";
export sayHi ="Hi";
file2.js:
import { sayHello, sayHi } from "./file1.js";
console.log(sayHello);
//-->"Hello"
console.log(sayHi);
//-->"Hi"
You can rename the named imports
import { sayHello as Hello, sayHi as Hi } from "./file1.js"
console.log(Hello);
//-->"Hello"
You can import everything using *
import * from "./file1.js";
console.log(sayHello);
//-->"Hello"
Default export: You can only export one default object in a .js
file and then import that object in another .js
file. However, you don't need curly brackets when importing:
file1.js:
export default sayHello = "HelloWorld";
file2.js:
import sayHello from "./file1.js";
console.log(sayHello);
//-->"Hello"
Exporting a Class: Export/import are commonly use to export/import classes:
vehicle.js:
class Vehicle{
constructor(make,model,year){
this.make=make;
this.model=model;
this.year=year;
}
start(){
return `${this.make} ${this.model} ENGINE START`;
}
}
export default Vehicle;
car.js:
import Vehicle from "./vehicle.js"
class Car extends Vehicle{
constructor(make,model,year,numWheels){
super(make,model,year); //inherit make,model,year from Vehicle
this.numWheels = 4;
}
}
var newCar = new Car("Honda","Civic",2019)
newCar.numWheels
//-->4
newCar.start()
//-->"Honda Civic ENGINE START"
Hash map is an object that contains key-value pairs. Any value (including array, object, Boolean, number, function) can be used as a key or a value. A Hash map stores the insertion orders.
Define a new Hash Map:
let myMap = new Map;
Insert or set a key-value pair:
myMap.set(1,"something");
myMap.set(false,"something");
myMap.set([1,2,3],"something");
myMap.set({1:"abc"},"something");
Delete a key-value pair:
myMap.delete(false);
Check if a key exist:
myMap.has(1);
Check a map size:
myMap.size;
Get a value:
myMap.get(1);
Remove all key-value pairs:
myMap.clear();
.keys()
would return a map iterator of keys
.values()
would return a map iterator
You can iterate a map iterator using for
of
:
for (let [key, value] of myMap) {
console.log(key ' = ' value);
};
for (let key of myMap.keys()) {
console.log(key);
};
for (let value of myMap.values()) {
console.log(value);
};
More about hash map can be found at: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
A set is a collection of unique values. A set is not an ordered abstract data structure, which means you cannot sort a set or order doesn't matter.
Define a set:
const mySet = new Set([3,1,1,2,2,4]);
//--> {3,1,2,4}
Add a new value:
mySet.add(5);
//-->{3,1,2,4,5}
Check if a value exist:
mySet.has(3);
//-> true
Check a set’s size:
mySet.size;
//->5
Delete a value in a set:
mySet.delete(3);
//-->true
More about sets can be found at: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
A Generator is like a function, however, it can be paused and continue
Define a generator, yield
in a generator is almost the same to return
:
function* genValues(){
yield "first";
yield "second";
yield "third";
};
let myGen = genValues()
Run a generator:
myGen.next() //.next() run the gen and return an object
//--> {value:"first", done:false}
myGen.next().value //.value returns the next gen value
//--> "second"
myGen.next().done //.done returns the status of the gen
//--> false
myGen.next()
//-->{value:undefined, done:true}
try
would test the block of code for errors. The code will run normally until there's an error.
catch
would execute in case of there's an error in try
.
try{
UndefinedFunction(); //this function was not defined
}catch(err){
console.log("The error is " err);
}
//-->"The error is ReferenceError"
throw
allows you to raise a default error supported by the browser with your own message, or raise your own customized error.
The default errors are: EvalError
, RangeError
, ReferenceError
, SyntaxError
, TypeError
, URIError
.
You can use an if
statement in catch
block to check for a specific error.
try{
throw new ReferenceError("This is a customized ReferenceError")
}catch(err){
if(err instanceof ReferenceError){
console.log("This code run when there is a ReferenceError");
}else{
console.log("This code run when there is any other errors");
}
};
//-->"This code run when there is a ReferenceError"
finnaly
would execute regardless of try
catch
try{
let age = 16;
if(age >= 18){
console.log("You can view the content")
}else{
throw "You are not 18 to view the content";
};
}catch(err){
console.log(err)
}finally{
console.log("Here's the content, you gonna fake your age anyway")
}
//--> "You are not 18 to view the content"
//--> "Here's the content, you gonna fake your age anyway"
The
Promise
object represents the eventual completion (or failure) of an asynchronous call, and its resulting value.
Promise is one of the fundamental concepts in Asynchronous JavaScript, Ajax, React,...
Asynchronous JavaScript is simply when your code is not sequentially executed at a time. For example, setTimeout
, setInterval
, ajax calls,... that take a period of time to be fulfilled.
console.log("you want this executed first");
setTimeout(()=>{console.log("you want this executed second")},1000);
console.log("you want this executed third");
//-->"you want this executed first"
//-->"you want this executed third"
//after 1 sec
//-->"you want this executed second"
With the example above, your code doesn't wait for setTimeout
, however, you want your code to wait for that setTimeout
before continuing, that's why you need Promise
A Promise
has 4 main keywords: resolve
, then
, reject
,catch
:
resovle
means that the promise has been fulfilled, andthen
is executed.resovle
is almost the same to the wayreturn
worksreject
means that the promise has not been fulfilled, andcatch
is executed.reject
is almost the same to the wayreturn
works
const doHomework = new Promise(function(resolve,reject) {
let isDone = false;
if (isDone){
setTimeout(function(){
resolve("is done");
},1000)
}else{
setTimeout(function(){
reject("is not done");
},1000)
}
});
doHomework.then(function(homeworkResult){
console.log("The homework " homeworkResult);
}).catch(function(homeworkResult){
console.log("The homework " homeworkResult);
})
//-->"The homework is not done"
A chain of tasks can be sequentially executed.
const doHomework = function(){
return new Promise(function(resolve,reject){
setTimeout(function(){
resolve("Do Homework, ");
console.log("Finished homework")
},1000);
})
};
const haveDinner = function(message){
return new Promise(function(resolve,reject){
setTimeout(function(){
resolve(message "then " "have dinner, ");
console.log("Finished dinner")
},1000);
})
};
const takeShower= function(message){
return new Promise(function(resolve,reject){
setTimeout(function(){
resolve(message "then " "take shower, ");
console.log("Finished shower")
},1000);
})
};
//call doHomework -> haveDinner -> takeShower
doHomework().then(function(message){
return haveDinner(message);
}).then(function(message){
return takeShower(message);
}).then(function(message){
console.log(message,"all finished ")
})
//-->Finished homework
//-->Finished dinner
//-->Finished shower
//-->Do Homework, then have dinner, then take shower, all finished
Promise.all
: Call multiple tasks at the same time, only trigger then
or catch
when all of the tasks have been fulfilled/rejected:
Promise.all([doHomework(),haveDinner(),takeShower()])
.then(function(){
console.log("all finished");
});
Promise.race
: Call multiple tasks at the same time, trigger then
or catch
when one of the tasks has been fulfilled/rejected:
Promise.race([doHomework(),haveDinner(),takeShower()])
.then(function(){
console.log("one finished");
});
The ansync
keyword that placed before a function makes that the function behave like a Promise
:
async function myFunc(){
return "this is a promise";
}
myFunc().then((val)=>{console.log(val)});
//-->"this is a promise"
In an async
function, the return
keyword will act like the resolve
keyword in a Promise
, the throw
keyword will act like the reject
keyword in a Promise
async function doHomework(){
let isDone = false;
if (isDone){
return("is done");
}else{
throw "is not done";
}
}
doHomework().then(function(homeworkResult){
console.log("The homework " homeworkResult);
}).catch(function(homeworkResult){
console.log("The homework " homeworkResult);
})
//"The homework is not done"
The await
keyword is ONLY used in the async
function. The await
keyword makes your code wait until the Promise
inside the function has been fulfilled/rejected:
async function myFunc(){
let myPromise = new Promise((resolve,reject)=>{
setTimeout(()=>{resolve("done!")},1000)
});
let result = await myPromise; //wait for this promise before continuing
return result;
}
myFunc().then((result)=>{console.log(result)})
Released under MIT License
Copyright (c) 2019 DevSocial.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.