Let & Const
To declare variables which are only available in a scope {}.
var x = 10; if (condition) { let x = 2; // Here x is 2 } // Here x is 10
The let will also declare a new variable in each loop iteration:
for (var i = 0; i < 5; i++) { setTimeout(function () { console.log(i); }, 1000); }
// 5 5 5 5 5 every second
// because i is a global variable and it is 5 when the callback function executes
for (let i = 0; i < 5; i++) { setTimeout(function () { console.log(i); }, 1000); }
// 1 2 3 4 5 every second
// because we have 5 separate local variables named i for each callback function in each loop
Let variables will not be properties of window object.
Const is similar to let, but the value can not be changed.
const a = function(x) {return x*x;}
For of
To loop over iterable data structures such as Arrays, Strings, Maps, NodeLists, ...
let text = ""; for (let x of 'Hello') { text += x + " "; } // 'H e l l o'
Functions
In ES6, functions can be defined in short ways (arrow functions):
// 1. No parameter const x = () => 'Hello'; // == function x() {return 'Hello';} // 2. Single parameter const x = a => a * a; // == function x(a) {return a * a;} // 3. Multiple parameters const x = (a, b) => a * b; // == function x(a, b) {return a * b;} // 4. Statement inside function const x = a => { console.log('square'); return a * a };
Arrow functions have no their own this so they are not suited for defining objects.
Functions in ES6 can have a default value for their parameters
const f = (a, b = 10) => a * b; f(2); // 20 f(2,30); // 60
You can also use (...) to allow a function to treat an indefinite number of arguments as an array:
function sum(...nums) { let sum = 0; for (let num of nums) sum += num; return sum; } let x = sum(4, 9, 16, 25, 29, 100, 66, 77); // 326
Symbol
Symbol is a datatype which will return a unique "hidden" value.
let a = Symbol(); let b = Symbol(); console.log(a, b); // Symbol() Symbol() (because they are hidden) console.log(a == b); // false (because they are unique)
String
You can use .include() method of String to check if a string has a sub string in it
"Hello world, welcome to the universe".includes("world"); // Returns true
You can use .startsWith() and .endsWith() method of String to check if a string starts or ends with a specific string
"Hello world, welcome to the universe".startsWith("Hello"); // Returns true "Hello world, welcome to the universe".endsWith("Hello"); // Returns false
Array
You can use Array.from() to create an array from an iterable object
Array.from("ABCDEFG"); // Returns [A,B,C,D,E,F,G]
To create the array of keys of an array, use .keys() method.
const fruits = ["Banana", "Orange", "Apple", "Mango"];
const keys = fruits.keys();
let text = "";
for (let x of keys) {
text += x + " ";
}
// '0 1 2 3 '
To find a value in an array, use .find() to return the occurred value and .findIndex() to return the index of the occurred value.
const nums = [4, 9, 16, 25, 29]; let first = nums.find((value, index, array) => value > 18); // 25 let firstIndex = nums.findIndex((value, index, array) => value > 18); // 3
Number
ES6 added some new properties and methods to the Number object, as well as new global number methods:
Number.EPSILON; // 2.220446049250313e-16 Number.MIN_SAFE_INTEGER; // -9007199254740991 Number.MAX_SAFE_INTEGER; // 9007199254740991 // check if a value is integer Number.isInteger(10); // true Number.isInteger(10.5); // false Number.isInteger('10'); // false // check if a value is out range of safe integer. Number.isSafeInteger(10); // returns true Number.isSafeInteger(12345678901234567890); // returns false // check if a value is infinity or NaN isFinite(10/0); // false isFinite(10/1); // true isFinite('1.5'); // true // check if a value is not a number isNaN("Hello"); // true, it's not a number isNaN("1.5"); // false, it's a number isNaN(1.48); // false, it's a number
Math
ES6 added some new methods to the Math object:
// .trunc(x) returns the integer part of x
Math.trunc(4.5); // 4
Math.trunc(-4.5); // -4
// .sign(x) return the status of x
Math.sign(33); // 1
Math.sign(-33); // -1
Math.sign(0); // 0
Math.sign('0'); // 0
Math.sign(''); // 0
Math.sign(null); // 0
Math.sign(undefined); // NaN
// .cbrt(x) return the cube root of x
Math.cbrt(8); // 2
// .log2(x) and .log10(x) return the base 2 and 10 logarithm of x
Math.log2(2); // 1
Math.log10(10); // 1
Class
To define a template for objects. constructor is the default function which will execute when a new object is declared.
class Car { constructor(name, speed) { this.name = name; this.speed = speed; } travelTime(distance) { return distance/this.speed; } } let my_car = new Car('Ford', 150); // Car {name: 'ford', speed: 150} my_car.travelTime(300); // 2 hours
You can use instanceof to compare the type of an object with a class
console.log(my_car instanceof Car); // true console.log(my_car instanceof Object); // true
Map
Map is an iterable object where the keys can be any datatype.
Declare
const john = {name: 'John Doe'},
lily = {name: 'Lily Bush'},
peter = {name: 'Peter Drucker'};
// pass an array or using set() method
const users = new Map([
[john, 'admin'],
[lily, 'editor'],
[peter, 'subscriber']
]);
Methods and Properties
clear()
– removes all elementsdelete(key)
– removes an element specified by the key. Returns true if the element is exist, otherwise, returns false.entries()
– returns a new iterator that contains an array of[key, value]
for each element. The order is the same as the insertion order.for (let [key, value] of users.entries()) { console.log(`${key.name}: ${value}`); } // John Doe: admin // Lily Bush: editor // Peter Drucker: subscriber // or you can convert entries to an array using ... (spread operand) var roles = [...users.entries()]; // [ Array, Array, Array ]
forEach(callback[, thisArg])
– invokes a callback for each key-value pair in the map in the insertion order. The optional thisArg parameter sets the this value for each callback.users.forEach((key, value) => console.log(`${key.name}: ${value}`) ); // John Doe: admin // Lily Bush: editor // Peter Drucker: subscriber
get(key)
– returns the value associated with the key. Returns undefined if the key is not existhas(key)
– returns true if a value associated with the key exists, otherwise, returns false.keys()
– returns a new iterator that contains the keys in insertion order.for (let user of users.keys()) { console.log(user.name); } // John Doe // Lily Bush // Peter Drucker // or you can convert keys to an array using ... var keys = [...users.keys()]; /* [{ name: 'John Doe' }, { name: 'Lily Bush' }, { name: 'Peter Drucker' } ] */
set(key, value)
– sets the value for a key or add a new element (returns the map object itself so other methods can be chained)let alex = {name: 'Alex Fig'}; users.set(alex, 'Reader').set(lily, 'Supporter');
values()
- returns a new iterator that contains values in insertion order.for (let role of users.values()) { console.log(role); } // admin // editor // subscriber // or you can convert values to an array using ... var roles = [...users.values()]; // [ 'admin', 'editor', 'subscriber' ]
size
- the number of elements
Set
Set is an iterable object where the values are unique
Declare
// pass an array or using add() method
let chars = new Set(['a', 'a', 'b', 'c', 'c']); // result in 3 elements 'a', 'b', 'c' because they are unique
// for of
for (let value of chars) { console.log(value); } // a b c
Methods and Properties
add(value)
– appends a new element with a specified value to the set (returns the set object itself so other methods can be chained)clear()
– removes all elementsdelete(value)
– deletes an element specified by the value.entries()
– returns a new iterator that contains an array of[value, value]
for (let [key, value] of chars.entries()) { console.log(key, value); } // a a // b b // c c // you can use spread operand to convert to an array as MAP
forEach(callback [, thisArg])
– invokes a callback on each element of theSet
with thethis
value sets tothisArg
in each call.chars.forEach(value => console.log(value)); // a b c
has(value)
– returnstrue
if an element with a given value is in the set, orfalse
if it is not.values()
=keys()
– returns a new iterator with all valuessize
– the number of elements
Promise
Declare and Use
Promise is an object that has state and result value, and it works asynchronously.
function makePromise(completed, time) { // the fulfilled and rejected functions are conventional, you don't need to define them // you can use any name for the functions return new Promise(function (fulfilled, rejected) { setTimeout(() => { if (completed) { fulfilled("Succeed"); // Can be any data type } else { rejected("Fail"); // Can be any data type } }, time); }); } // when declare, good_promise will immediately have // promiseState = 'pending' // promiseResult = undefined let good_promise = makePromise(true, 3000); // after 3 seconds, will send out the value = "Succeed" // promiseState = 'fulfilled' // promiseResult = 'Succeed' good_promise.then( successValue => console.log(successValue), failValue => console.log(failValue) ); // do a bad promise let bad_promise = makePromise(false, 3000); // after 3 seconds // will throw an error with message = "Fail" // and send out the value = "Fail" // promiseState = 'rejected' // promiseResult = 'Fail' bad_promise.then( successValue => console.log(successValue), failValue => console.log(failValue) );
You can use then() to only catch the successValue, whereas, you can use catch() to only catch the failValue and use finally() to do things at the end of the whole process (no matter the result is)
my_promise
.then(success => console.log(success))
.catch(fail => console.log(fail))
.finally(() => {console.log('Finished');});
Chain
You can call then() consecutively and the return value from previous then() will be passed as the parameter of the next then(). You can return any data type in then(), even a new promise if you wish.
function showMessage(message, time) { return new Promise((resolve, reject) => { setTimeout(() => {resolve(message);}, time); }); } console.log('You have 3 seconds to prepare'); showMessage('3 + 5 = __ ? Please think in 5 second', 3000) .then((result) => { console.log(result); return showMessage('You have 3 seconds to answer', 5000); }) .then((result) => { console.log(result); return showMessage('The answer is 8. Please double check', 3000); }) .then((result) => { console.log(result); }) ; /* You have 3 seconds to prepare 3 + 5 = __ ? Please think in 5 second You have 3 seconds to answer The answer is 8. Please double check */
All method
You can use the all() method of Promise to combine results from many promises as a new result.
const num = x => new Promise(f => f(x)) Promise.all([num(10), num(20), num(30)]) .then(results => { const total = results.reduce((prev, current) => prev + current); console.log(`Results: ${results}
`); console.log(`Total: ${total}
`); }) ; // Results: 10,20,30 // Total: 60
Race method
You can use race() method of Promise to catch the first resolved promise from an array of promises
const p1 = new Promise(resolve => {
setTimeout(() => { resolve(10); }, 1000);
});
const p2 = new Promise(resolve => {
setTimeout(() => { resolve(20); }, 2000);
});
Promise.race([p1, p2]).then(value => console.log(`Resolved: ${value}`))
// Resolved 10 (after 1 second)