34
ES2015 Academy PRO Binary Studio binary-studio.c

Academy PRO: ES2015

Embed Size (px)

Citation preview

Page 1: Academy PRO: ES2015

ES2015Academy PRO

Binary Studio

binary-studio.com

Page 2: Academy PRO: ES2015

Version history

Page 3: Academy PRO: ES2015

Why- Be a better language

- Improve language for writing libraries, DOM etc.

- Improve interoperation

Page 4: Academy PRO: ES2015

Design principles- Backwards compatible - One JavaScript

- Yearly iterations

Page 5: Academy PRO: ES2015

Variables and scopinglet

function order(x, y) { if (x > y) { // (A) let tmp = x; x = y; y = tmp; } console.log(tmp===x);

// ReferenceError: tmp is not defined return [x, y];}

сonst

const foo; // SyntaxError: missing = in const declaration

const bar = 123;bar = 456; // TypeError: `bar` is read-only

Object.freeze()

Page 6: Academy PRO: ES2015

Variables and scopinglet tmp = true;if (true) { // enter new scope, TDZ starts // Uninitialized binding for `tmp` is created console.log(tmp); // ReferenceError

let tmp; // TDZ ends, `tmp` is initialized with `undefined` console.log(tmp); // undefined

tmp = 123; console.log(tmp); // 123}console.log(tmp); // true

Page 7: Academy PRO: ES2015

Variables and scopingconst arr = [];for (var i=0; i < 3; i++) { arr.push(() => i);}arr.map(x => x()); // [3,3,3]

const arr = [];for (let i=0; i < 3; i++) { arr.push(() => i);}arr.map(x => x()); // [1,2,3]

Page 8: Academy PRO: ES2015

Number and MathNumber.EPSILON

Number.isSafeInteger(number)

Number.MIN_SAFE_INTEGER

Number.MAX_SAFE_INTEGER

Number.isFinite(Infinity)

Number.isNaN(x)

Math.sinh(x)...

> 0.1 + 0.2 === 0.3false

Page 9: Academy PRO: ES2015

Strings> 'hello'.startsWith('hell')true> 'hello'.endsWith('ello')true> 'hello'.includes('ell')true> 'doo '.repeat(3)'doo doo doo '

Page 10: Academy PRO: ES2015

Template literalsconst firstName = 'Jane';console.log(`Hello ${firstName}!How are youtoday?`);

// Output:// Hello Jane!// How are you// today?

const str = `BEFOREAFTER`;console.log(str === 'BEFORE\nAFTER'); // true

tagFunction`Hello ${firstName} ${lastName}!`tagFunction(['Hello ', ' ', '!'], firstName, lastName)

> String.raw`\n` === '\\n'true

Page 11: Academy PRO: ES2015

SymbolsString.prototype.contains clashed with a method added by MooTools and had to be renamed to String.prototype.includes

const COLOR_RED = 'Red';

const COLOR_RED = Symbol('Red');

Symbol.hasInstance (method)

Symbol.toPrimitive (method)

Symbol.toStringTag (string)

Symbol.unscopables (Object)

Symbol.iterator (method)

Symbol.species (method)

Symbol.for(str) : symbolSymbol.keyFor(sym) : string

Page 12: Academy PRO: ES2015

Maps and Sets> const map = new Map(); // create an empty Map> const KEY = {};

> map.set(KEY, 123);> map.get(KEY)123> map.has(KEY)true> map.delete(KEY);true> map.has(KEY)false

const arr = [5, 1, 5, 7, 7, 5];const unique = [...new Set(arr)]; // [ 5, 1, 7 ]

Page 13: Academy PRO: ES2015

Destructuringconst obj = { first: 'Jane', last: 'Doe' };const {first: f, last: l} = obj; // f = 'Jane'; l = 'Doe'

// {prop} is short for {prop: prop}const {first, last} = obj; // first = 'Jane'; last = 'Doe'

const iterable = ['a', 'b'];const [x, y] = iterable; // x = 'a'; y = 'b'

const obj = { a: [{ foo: 123, bar: 'abc' }, {}], b: true };const { a: [{foo: f}] } = obj; // f = 123

const [x] = []; // x = undefinedconst {prop:y} = {}; // y = undefined

const [x=3, y] = []; // x = 3; y = undefinedconst {foo: x=3, bar: y} = {}; // x = 3; y = undefined

Page 14: Academy PRO: ES2015

Parameter handlingfunction selectEntries({ start=0, end=-1, step=1 } = {}) {}

selectEntries({ start: 10, end: 30, step: 2 });selectEntries({ step: 3 });selectEntries({});selectEntries();

function multiply(x=1, y=1) { return x * y;}

/** * Called if a parameter is missing and * the default value is evaluated. */function mandatory() { throw new Error('Missing parameter');}function foo(mustBeProvided = mandatory()) { return mustBeProvided;}

Page 15: Academy PRO: ES2015

Rest and Spreadfunction f(...args) { if (args.length > 2) { throw new Error(); } // Extract the real parameters let [x, y] = args;}

> Math.max(...[-1, 5, 11, 3])11

const arr1 = ['a', 'b'];const arr2 = ['c', 'd'];

arr1.push(...arr2);// arr1 is now ['a', 'b', 'c', 'd']

Page 16: Academy PRO: ES2015

Arrow functionsconst arr = [1, 2, 3];const squares = arr.map(x => x * x);

// Traditional function expression:const squares = arr.map(function (x) { return x * x });

function UiComponent() { const button = document.getElementById('myButton'); button.addEventListener('click', () => { console.log('CLICK'); this.handleClick(); // lexical `this` });}

> [1,2,3].map(x => 2 * x)[ 2, 4, 6 ]

> [[1,2], [3,4]].map(([a,b]) => a + b)[ 3, 7 ]

(function () { // open IIFE // inside IIFE}()); // close IIFE

(() => { return 123})();

Page 17: Academy PRO: ES2015

Object literalconst obj = { myMethod(x, y) { }};

const first = 'Jane';const last = 'Doe';const obj = { first, last };

const obj = { ['h'+'ello']() { return 'hi'; }};console.log(obj.hello()); // hi

const obj = { get foo() { console.log('GET foo'); return 123; }, set bar(value) { console.log('SET bar to '+value); // return value is ignored }};

Page 18: Academy PRO: ES2015

Object const obj = { foo: 123 };Object.assign(obj, { bar: true });console.log(JSON.stringify(obj)); // {"foo":123,"bar":true}

Object.is(value1, value2)

> NaN === NaNfalse

> Object.is(NaN, NaN)true

Page 19: Academy PRO: ES2015

Classesclass Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return `(${this.x}, ${this.y})`; }}

class ColorPoint extends Point { constructor(x, y, color) { super(x, y); this.color = color; } toString() { return super.toString() + ' in ' + this.color; }}

function functionThatUsesBar() { new Bar();}

functionThatUsesBar(); // ReferenceErrorclass Bar {}functionThatUsesBar(); // OK

class Foo { static classMethod() { return 'hello'; }}

class Bar extends Foo {}Bar.classMethod(); // 'hello'

Page 20: Academy PRO: ES2015

Classesclass Foo {}

class Bar extends Foo { constructor(num) { const tmp = num * 2; // OK this.num = num; // ReferenceError super(); this.num = num; // OK }}

constructor(...args) { super(...args);}

class Employee extends Person { constructor(name, title) { super(name); this.title = title; } toString() { return `${super.toString()} (${this.title})`; }}

Page 21: Academy PRO: ES2015

Species patternconst a = new SortedArray(1,2,3);

a.map(x => x * 2);

class MyArray1 extends Array { static get [Symbol.species]() { return Array; }}

Page 22: Academy PRO: ES2015

Modules//------ lib.js ------export const sqrt = Math.sqrt;export function square(x) { return x * x;}export function diag(x, y) { return sqrt(square(x) + square(y));}

//------ main.js ------import { square, diag } from 'lib';console.log(square(11)); // 121console.log(diag(4, 3)); // 5

//------ main.js ------import * as lib from 'lib';console.log(lib.square(11)); // 121console.log(lib.diag(4, 3)); // 5

//------ myFunc.js ------export default function () { ··· } // no semicolon!

//------ main1.js ------import myFunc from 'myFunc';myFunc();

Page 23: Academy PRO: ES2015

ModulesSystem.import('some_module').then(some_module => { // Use some_module}).catch(error => { ···});

Promise.all( ['module1', 'module2', 'module3'] .map(x => System.import(x))).then(([module1, module2, module3]) => { // Use module1, module2, module3});

<script type="module"> import $ from 'lib/jquery'; var x = 123;

// The current scope is not global console.log('$' in window); // false console.log('x' in window); // false

// `this` still refers to the global object console.log(this === window); // true</script>

Page 24: Academy PRO: ES2015

Arrayconst spans = document.querySelectorAll('span.name');

// map(), generically:const names1 = Array.prototype.map.call(spans, s => s.textContent);

// Array.from():const names2 = Array.from(spans, s => s.textContent);

class MyArray extends Array { ···}console.log(MyArray.of(3, 11, 8) instanceof MyArray); // trueconsole.log(MyArray.of(3).length === 1); // true

Page 25: Academy PRO: ES2015

ArrayArray.prototype.entries()

Array.prototype.keys()

Array.prototype.values()

> [6, -5, 8].find(x => x < 0)-5

> [6, -5, 8].findIndex(x => x < 0)1

> const arr = [];> Array.isArray(arr)true

Page 26: Academy PRO: ES2015

for-ofconst iterable = ['a', 'b'];for (const x of iterable) { console.log(x);}

// Output:// a// b

const arr = ['a', 'b', 'c'];for (const [k,v] of arr.entries()) { console.log(`key = ${k}, value = ${v}`);}

Page 27: Academy PRO: ES2015

Iterables and iteratorsinterface Iterable { [Symbol.iterator]() : Iterator;}

interface Iterator { next() : IteratorResult;}

interface IteratorResult { value: any; done: boolean;}

Page 28: Academy PRO: ES2015

Generatorsfunction* genFunc() { // (A) console.log('First'); yield; // (B) console.log('Second'); // (C)}

> const genObj = genFunc();> genObj.next()First{ value: undefined, done: false }

> genObj.next()Second{ value: undefined, done: true }

const obj = { * generatorMethod() { ··· } }; const genObj = obj.generatorMethod();

class MyClass { * generatorMethod() { ··· } } const myInst = new MyClass(); const genObj = myInst.generatorMethod();

Page 29: Academy PRO: ES2015

Generatorsfunction* genFuncWithReturn() { yield 'a'; yield 'b'; return 'result';}

function* gen() { // (A) while (true) { const input = yield; // (B) console.log(input); }}const obj = gen();obj.next('a');obj.next('b');

Page 30: Academy PRO: ES2015

Promisesfunction asyncFunc() { return new Promise( function (resolve, reject) { ··· resolve(value); // success ··· reject(error); // failure });}

asyncFunc().then(value => { /* success */ }).catch(error => { /* failure */ });

asyncFunc1().then(value1 => { // Success: use value1 return asyncFunction2(); // (A)}).then(value2 => { // (B) // Success: use value2}).catch(error => { // Failure: handle errors of // asyncFunc1() and asyncFunc2()});

Page 31: Academy PRO: ES2015

PromisesPromise.all(promisedTexts).then(texts => { for (const text of texts) { console.log(text); }}).catch(reason => { // Receives first rejection among the Promises});

Promise.race([ httpGet('http://example.com/file.txt'), delay(5000).then(function () { throw new Error('Timed out') });]).then(function (text) { ··· }).catch(function (reason) { ··· });

Page 32: Academy PRO: ES2015

CSPco(function* () { try { const [croftStr, bondStr] = yield Promise.all([ getFile('http://localhost:8000/croft.json'), getFile('http://localhost:8000/bond.json'), ]); const croftJson = JSON.parse(croftStr); const bondJson = JSON.parse(bondStr);

console.log(croftJson); console.log(bondJson); } catch (e) { console.log('Failure to read: ' + e); }});

Page 33: Academy PRO: ES2015

Proxiesconst target = {};const handler = { get(target, propKey, receiver) { console.log('get ' + propKey); return 123; }};const proxy = new Proxy(target, handler);

> proxy.fooget foo123

const handler = { deleteProperty(target, propKey) { console.log('DELETE ' + propKey); return delete target[propKey]; }, has(target, propKey) { console.log('HAS ' + propKey); return propKey in target; }, // Other traps: similar}

Page 34: Academy PRO: ES2015

The End