Variables declared with var are function-scoped while those declared with let/const are block-scoped.
ES6 does not perform type check, which means a value of type number can be assigned to a variable of original type string, even if using let in ES6.
blcoks & IIFEs
A block:
1 2 3 4 5
{ const a = 1; let b = 2; } console.log(a, b); // error because a and b are not defined.
Strings in ES6 / ES2015
1 2 3 4 5 6 7
let firstName = 'John'; let lastName = 'Smith'; const yearOfBirth = 1990; // ES5: let outputStr = 'This is ' + firstName + ' ' + lastName + '. He was born in ' + yearOfBirth. // ES6: let outputStr = `This is ${firstName}${lastName}. He was born in ${yearOfBirth}.`;
New methods included in string objects:
1 2 3 4 5
const n = "John Smith"; let result = n.startWith("J"); let result = n.endWith("Sm"); let result = n.includes(" "); let result = n.repeat(5);
Arrorw Functions
Compared with traditional declared functions, Arrow functions DO NOT have their own this keyword, when accessing this keyword in arrow functions, it references its parent function(s)’ this keyword. This is called lexical this keyword.
// ES5 var box5 = { color: "green", position: 1, clickMe: function () { var self = this; document.querySelector(".green").addEventListener("click", function () { var str = "This is box number " + self.position + " and it is " + self.color; alert(str); }); }, }; box5.clickMe();
// ES6 const box6 = { color: "green", position: 1, clickMe: function () { document.querySelector(".green").addEventListener("click", () => { let str = "This is box number " + this.position + " and it is " + this.color; alert(str); }); }, }; box6.clickMe();
//ES5 var Person5 = function (name, yearOfBirth, job) { this.name = name; //... }; // add a method to the prototype Person5.prototype.calculateAge = function () { var age = newDate().getFullYear() - this.yearOfBirth; }; // inheritance begins var Athlete5 = function (name, yearOfBirth, job, olymicGames, medals) { // We don't use `new` keyword here because constructing Athelete5 object will use `new` keyword, while `new` keyword will create an empty object and calls the function constructor of Athelete5 and set `this` keyword to the newly created empty object. Person5.call(this, name, yearOfBirth, job); this.olymicGames = olymicGames; this.medals = medals; }; // use object.create() to create a new object with the prototype same as Person5, and assign it to prototyoe of Athelete5. That's the way how inherited classes' prototype gets correctly connected to super classes' prototype. Athlete5.prototype = Object.create(Person5.prototype);
Athlete5.prototype.wonMedal = function () { this.medals++; console.log(this.medals); };
var johnAthlete5 = new Athlete5("John", 1990, "swimmer", 3, 10); johnAthlete5.calculateAge(); johnAthlete5.wonMedal();
// produce a Promise const getIds = newPromise((resolve, reject) => { setTimeout(() => { // mark the promise as `Fulfilled` and return the given data resolve([523, 883, 432, 974]); }, 1500); }); // consume a Promise getIds .then((IDs) => { // correspond to `fulfilled` //... returnnewPromise((resolve, reject) => {}); }) .then((recipe) => { console.log(recipe); }) .catch((error) => { // correspond to `reject` //... });
Core promises methods from bluebird:
Promise.promisify: Wrap an Async method for the given function to that object.
Promise.promisifyAll: Wrap Async methods for all functions to the given object.
Promise.fromCallback: Returns a promise that is resolved by a node style callback funnction.
Promise.resolve: Create a promise that is resolved with the given value.
Promise.reject: Create a promise that is rejected with the given error.
.catch: A catch-all variant similar to catch(e) {} block. A filtered variant that lets you only handle specific errors. This one is usually preferable.
.error: Like .catch but instead of catching all types of exceptions, it only catches operational errors.
async function always runs on the background, await keyword will stop the execution until the promise is marked as Fulfilled. For Rejected state we need to surround a catch block. Async function always return a Promise.
ES6 Modules
Exports
export can be followed up with expressions of any type in javascript.
Default Export: works when you only want to export one thing from a module. The sytax is export default.
Named Export: works when you want to export multiple things from one module. When importing things from such a module, we need to use { } with the exact names(or use as {alias}) of that exported in the module. For example: import { add, multiply } from '...'
Import everything: import * as searchView from '...'
data-{customize} attributes allows to store customized data in HTML5 element, and it will wrap the {customize} as a property of element.dataset, thus access it by using element.dataset.customize. See more here
TypeScript uses declaration files to understand the types and function signatures of a module. To take advantage of Typescript’s static type checker. We’ll need to start adding type annotations to our code, including code from 3rd-party npm modules.
use multipart/form-data when your form includes any <input type="file"> elements, otherwise you can use multipart/form-data or application/x-www-form-urlencoded but application/x-www-form-urlencoded will be more efficient