workshop 10: ecmascript 6

49
Front End Workshops IX. ECMAScript 6. Novelties. Browser support Alex Adrià Cuadripani [email protected] Mario García Martín [email protected]

Upload: visual-engineering

Post on 14-Jan-2017

331 views

Category:

Software


0 download

TRANSCRIPT

Page 1: Workshop 10: ECMAScript 6

Front End Workshops

IX.ECMAScript 6. Novelties. Browser support

Alex Adrià [email protected]

Mario García Martí[email protected]

Page 2: Workshop 10: ECMAScript 6

Introduction

— INTRODUCTIO —

Page 3: Workshop 10: ECMAScript 6

ECMAScript 6

Also known as ECMAScript 2015 or simply ES6

First working draft published on July 2011

Officially approved on June 2015

Implementation in major JavaScript engines is underway

Page 4: Workshop 10: ECMAScript 6

More information in...

● http://www.ecma-international.org/ecma-262/6.0/index.html

● http://kangax.github.io/compat-table/es6/

Page 5: Workshop 10: ECMAScript 6

ES6 Novelties

— ES6 NOVITATIS —

Page 6: Workshop 10: ECMAScript 6

Default parameters

// ES5function multiply(a, b, c) {

b = typeof b !== 'undefined' ? b : 1;c = typeof c !== 'undefined' ? c : 1;console.log(a * b * c);

}

multiply(5); // 5

// ES6function multiply(a, b = 1, c = 1) {

console.log(a * b * c);}

multiply(5); // 5multiply(5, undefined, 2); // 10

// ES6function plurify(s, p = s + 's') {

console.log(s + ' ' + p); }

plurify('beer'); // 'beer beers'

// ES6function init(options = { 'param1': 1 }) {

console.log(options);}

init(); // { 'param1': 1 }init({ 'param': 2 }); // { 'param': 2 }

Additional usage...

Page 7: Workshop 10: ECMAScript 6

Rest parameters

function f(x, ...y) {console.log(x, y);

}

f(3, 'hello', true); // 3, ['hello', true]f(3, 'hello', true, false); // 3, ['hello', true, false]

// ES 5function logAllArguments() {

for (var i=0; i < arguments.length; i++) {console.log(arguments[i]);

}}

logAllArguments(1, 2, 3, 4, 5); // 1 2 3 4 5

// ES 6function logAllArguments(...args) {

for (var i=0; i < args.length; i++) {console.log(args[i]);

}}

logAllArguments(1, 2, 3, 4, 5); // 1 2 3 4 5

Could replace usage of the ‘arguments’ variable...

Page 8: Workshop 10: ECMAScript 6

Spread operator

function f(x, y, z) {console.log(x + y + z);

}

f(...[1, 2, 3]); // 6

// ES 5var numbers = [-1, 5, 11, 3];Math.max.apply(Math, numbers); // 11

// ES 6var numbers = [-1, 5, 11, 3];Math.max(...numbers); // 11

var x = ['a', 'b'];var y = ['c'];var z = ['d', 'e'];

var arr = [...x, ...y, ...z]; // ['a', 'b', 'c', 'd', 'e']

Practical uses

Page 9: Workshop 10: ECMAScript 6

for..of loopsvar numbers = [2, 3, 4];for (var value of numbers) {

console.log(value);}

// 2, 3, 4

var letters = 'Homer';for (var item of letters) {

console.log(item);}

// 'H', 'o', 'm', 'e', 'r'

Do we really need another way of looping?

// Classic wayfor (var i=0; i<numbers.length; i++) {

console.log(numbers[i]);}

// ES 5numbers.forEach(function(value) {

console.log(value);});

// for..infor (var i in numbers) {

console.log(numbers[i]);}

Page 10: Workshop 10: ECMAScript 6

var a = 5;var b = 10;console.log(`Fifteen is ${a + b} and not ${2 * a + b}.`); // 'Fifteen is 15 and not 20.'

Template strings

// ES 5var greetings = 'Hello\n' +

'How are you\n' +'today?';

// ES 6var greetings = `Hello

How are youtoday?`;

Offers support for multiple lines

Page 11: Workshop 10: ECMAScript 6

Destructuring

var homer = {name: 'Homer',surname: 'Simpson'

};

var { name, surname } = homer;

console.log(name); // 'Homer'console.log(surname); // 'Simpson'

// ES 5var foo = ['one', 'two', 'three'];

var one = foo[0];var two = foo[1];var three = foo[2];

// ES 6var foo = ['one', 'two', 'three'];

var [one, two, three] = foo;

var foo = function() { return [175, 75];

};

var [height, weight] = foo();

console.log(height); // 175console.log(weight); // 75

Page 12: Workshop 10: ECMAScript 6

const

const PI;PI = 3.14; // ERROR

const PI = 3.14;PI = 3.14159; // ERROR

const PI = 3.14;

Value must be assigned in declaration

Read-only

Block scoped

if (true) {const PI = 3.14;

}

console.log(PI); // ERROR

Characteristics

Page 13: Workshop 10: ECMAScript 6

let

var fns = [];for (var i=0; i<4; i++) {

fns.push(function() {console.log(i);

});}

fns[0](); // 4fns[1](); // 4fns[2](); // 4fns[3](); // 4

var fns = [];for (let i=0; i<4; i++) {

fns.push(function() {console.log(i);

});}

fns[0](); // 0fns[1](); // 1fns[2](); // 2fns[3](); // 3

Block scopedlet name = 'Homer';

In previous workshops...

“var”... Are we going to see you ever again?

Page 14: Workshop 10: ECMAScript 6

Block-level function declaration

'use strict';function f() { return 1; }

{console.log(f()); // 2

function f() { return 2; }console.log(f()); // 2

}

console.log(f()); // 1

Page 15: Workshop 10: ECMAScript 6

Arrow functions

// ES5var sum = function(a, b) {

return a + b;}

// ES6var sum = (a, b) => a + b;

function Person() {this.age = 0;

setInterval(() => {this.age++;

}, 1000);}

function Person() {var self = this;

self.age = 0;setInterval(function() {

self.age++;}, 1000);

}

// ES 5var data = ['one', 'two', 'three'];

data.forEach(function(value) {console.log(value)

});

// ES 6var data = ['one', 'two', 'three'];

data.forEach(value => { console.log(value);

});

Page 16: Workshop 10: ECMAScript 6

Class

// ES6class Media {

constructor(title, duration, isPlaying) {this.title = title;this.duration = duration;this.isPlaying = isPlaying;}

start() {this.isPlaying = true;

}

stop() {this.isPlaying = false;

}}

// ES5function Media(title, duration, isPlaying) {

this.title = title;this.duration = duration;this.isPlaying = isPlaying;

}

Media.prototype.start = function start() {this.isPlaying = true;

};

Media.prototype.stop = function stop() {this.isPlaying = false;

};

Page 17: Workshop 10: ECMAScript 6

Inheritance

// ES6class Song extends Media {

constructor(title, artist, duration) {super(title, duration, false);

this.artist = artist;}

}

class Movie extends Media {constructor(title, year, duration) {

super(title, duration, false);this.year = year;

}}

// ES5function Song(title, artist, duration) {

Media.call(this, title, duration, false);this.artist = artist;

}

Song.prototype = Object.create(Media.prototype);

function Movie(title, year, duration) {Media.call(this, title, duration, false);this.year = year;

}

Movie.prototype = Object.create(Media.prototype);

Page 18: Workshop 10: ECMAScript 6

Modules

// lib/math.jsexport function sum(x, y) {

return x + y;}

export const PI = 3.14159;

// lib/ux-math.jsexport * from 'lib/math';export const E = 2.7182;export default function(x) {

return Math.exp(x);}

// app.jsimport * as math from 'lib/math';

console.log(math.sum(math.PI, math.PI));

// otherApp.jsimport {sum, PI} from 'lib/math';

console.log(sum(PI, PI));

// app.jsimport exp, {PI, E} from 'lib/ux-math';

console.log(exp(PI));

Page 19: Workshop 10: ECMAScript 6

Generators

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

}

let genObj = genFunc();

genObj.next()

//First

{ value: undefined, done: false }

genObj.next()

//Second

{ value: undefined, done: true }

function* objectEntries(obj) {let keys = Object.keys(obj);

for (let key of keys) {yield [key, obj[key]];

}}

let batman = { first: 'Bruce', last: 'Wayne' };

for (let [key,value] of objectEntries(batman)) {

console.log(`${key}: ${value}`);

}

// Output:

// first: Bruce

// last: Wayne

Page 20: Workshop 10: ECMAScript 6

Typed Arrays

let typedArray = new Uint8Array([0,1,2]);

console.log(typedArray.length); // 3

typedArray[0] = 5;

let normalArray = [...typedArray]; // [5,1,2]

// The elements are stored in typedArray.buffer.

let dataView = new DataView(typedArray.buffer);

console.log(dataView.getUint8(0)); // 5

Page 21: Workshop 10: ECMAScript 6

Typed Arrays

Page 22: Workshop 10: ECMAScript 6

Map

let map = new Map();

map.set('name','Bruce');

map.set('surname','Wayne');

map.size //2

map.get('name'); //Bruce

map.has('name'); //true

map.delete('name'); //true

map.clear();

map.size //0

let map = new Map([

[1, 'one'],

[2, 'two'],

[3, 'three'],

]);

for (let [key, value] of map) {

console.log(key, value);

}

Page 23: Workshop 10: ECMAScript 6

WeakMap

//keys cannot be primitive types

let key = {a:1};

let wm = new WeakMap();

wm.set(key,"value");

wm.get(key); //you can get "value";

key=undefined;

console.log(wm.get(key));

console.log(wm.size); //undefined

//loop through the keys in an weakmap

doesn't work

for(let i of wm) {

console.log(i);

}

//delete all keys doesn't work

wm.clear();

Page 24: Workshop 10: ECMAScript 6

Set

let set = new Set();

set.add('luke');

set.add('yoda');

set.size //2

set.has('luke'); //true

set.delete('luke'); //true

set.has('luke'); //false

set.size //1

set.clear();

set.size //0

let set = new Set(['luke', 'yoda', 'ben']);

set = new Set().add('luke').add('yoda').add('ben');

for (let x of set) {

console.log(x);

}

Page 25: Workshop 10: ECMAScript 6

WeakSet

//values cannot be primitive types

let weakset = new WeakSet();

let obj = {name: 'Vito Corleone'};

weakset.add(obj);

weakset.add(function(){});

weakset.has({name: 'Vito Corleone'}); //false

weakset.has(obj); //true

obj = undefined;

weakset.delete(obj); //false

weakset.delete(function(){}); //false

weakset.size undefined

//loop through the values in an weakset

doesn't work

for (let x of weakset) {

console.log(x);

}

//delete all values doesn't work

weakset.clear();

Page 26: Workshop 10: ECMAScript 6

Proxy

let handler = {

get: function(target, name){

return name in target?

target[name] :

'not a jedi';

}

};

let proxy = new Proxy({}, handler);

proxy.a = 'ben';

proxy.b = 'yoda';

console.log(proxy.a, proxy.b); // ben, yoda

console.log(proxy.c); // not a jedi

let target = {}; // Start with an empty object

let handler = {}; // Don’t intercept anything

let {proxy, revoke} = Proxy.revocable(target,

handler);

proxy.foo = 123;

console.log(proxy.foo); // 123

revoke();

console.log(proxy.foo); // TypeError: Revoked

Page 27: Workshop 10: ECMAScript 6

Promises

var promise = new Promise(

function (resolve, reject) {

...

if (...) {

resolve(value); // success

} else {

reject(reason); // failure

}

});

● Pending: the result hasn’t been computed, yet

● Fulfilled: the result was computed successfully

● Rejected: a failure occurred during computation

Page 28: Workshop 10: ECMAScript 6

Promises

function httpGet(url) {

return new Promise(

function (resolve, reject) {

var request = new XMLHttpRequest();

request.onreadystatechange = function () {

if (this.status === 200) {

resolve(this.response);

//success

} else {

// Something went wrong (404 etc.)

reject(new Error(this.statusText));

}

}

Page 29: Workshop 10: ECMAScript 6

Promises

request.onerror = function () {

reject(new Error('XMLHttpRequest Error: '+this.statusText));

};

request.open('GET', url);

request.send();

});

}

Page 30: Workshop 10: ECMAScript 6

Promises

httpGet('http://myserver.com/example')

.then(

function (value) {

console.log('Contents: ' + value);

},

function (reason) {

console.error('Something went wrong', reason);

});

Page 31: Workshop 10: ECMAScript 6

Object static methods

var original = {};

var merged = {};

original.a = 1;

merged.b = 2;

Object.assign(original, merged);

console.log(original.b) //2

Object.assign(target, source_1, ..., source_n)

Object.is(value1, value2)

Object.is(2, 2) //true

Object.is('test', 'aaa') //false

Object.is(NaN, NaN) //true

Object.is(-0, +0) //false

Page 32: Workshop 10: ECMAScript 6

Object static methods

var human = {

sleep() {

return 'sleeping...';

}

};

var worker = {

work() {

return 'working...';

},

};

Object.setPrototypeOf(worker, human);

worker.sleep(); //sleeping...

Object.setPrototypeOf(obj, prototype);

Page 33: Workshop 10: ECMAScript 6

String static methods

let name = 'Bob';

String.raw`Hi\n${name}!`;

// 'Hi\\nBob!', substitutions are processed.

String.raw`templateString`;

String.fromCodePoint(42); // "*"

String.fromCodePoint(65, 90); // "AZ"

String.fromCodePoint(0x404); // "\u0404"

String.fromCodePoint('_'); // RangeError

String.fromCodePoint(num1[, ...[, numN]])

Page 34: Workshop 10: ECMAScript 6

String.prototype methods

'abc'.repeat(2); // 'abcabc'

String.prototype.repeat

'Ser, o no ser.'.startsWith('Ser'); // true

String.prototype.startsWith

'Ser, o no ser.'.endsWith('ser.'); // true

String.prototype.endsWith

'Ser, o no ser.'.includes('no'); // true

String.prototype.includes

Page 35: Workshop 10: ECMAScript 6

Array static methods

// Array-like primitive types to Array

Array.from([1, 2, 3]);

//[1, 2, 3]

// Any iterable object...

// Set

var s = new Set(["foo", window]);

Array.from(s);

// ["foo", window]

Array.from(arrayLike[, mapFn[, thisArg]])

// Map

var m = new Map([[1, 2], [2, 4], [4, 8]]);

Array.from(m);

// [[1, 2], [2, 4], [4, 8]]

// String

Array.from("foo");

// ["f", "o", "o"]

// Using an arrow function as the map

function to manipulate the elements

Array.from([1, 2, 3], x => x + x);

// [2, 4, 6]

Page 36: Workshop 10: ECMAScript 6

Array static methods

Array.of(1); // [1]

Array.of(1, 2, 3); // [1, 2, 3]

Array.of(undefined); // [undefined]

//The difference between Array.of() and the Array constructor is in the handling of

//integer arguments: Array.of(42) creates an array with a single element, 42, whereas

//Array(42) creates an array with 42 elements, each of which is undefined.

Array.of(element0[, element1[, ...[, elementN]]])

Page 37: Workshop 10: ECMAScript 6

Array.prototype methods

Array.from([ 'a', 'b' ].keys()); //[ 0, 1 ]

Array.prototype.keys()

Array.from([ 'a', 'b' ].values()); //[ 'a', 'b' ]

Array.prototype.values()

Array.from([ 'a', 'b' ].entries()); //[ [ 0, 'a' ], [ 1, 'b' ] ]

for (let [index, elem] of ['a', 'b'].entries()) {

console.log(index, elem);

}

Array.prototype.entries()

Page 38: Workshop 10: ECMAScript 6

Array.prototype methods

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

Array.prototype.find(predicate, thisArg?)

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

Array.prototype.findIndex(predicate, thisArg?)

['a', 'b', 'c'].fill(7); //[ 7, 7, 7 ]

['a', 'b', 'c'].fill(7, 1, 2); //[ 'a', 7, 'c' ]

Array.prototype.fill(value, start?, end?)

Page 39: Workshop 10: ECMAScript 6

Number properties

Number.isFinite(Infinity);

//false

Number.isFinite(NaN);

//false

Number.isFinite(number)

Number.isInteger(number)

Number.isFinite(123);

//true

Number.isInteger(-17);

//true

Number.isInteger(33);

//true

Number.isInteger(33.1);

//false

Number.isInteger('33');

//false

Number.isInteger(NaN);

//false

Number.isInteger(Infinity);

//false

Page 40: Workshop 10: ECMAScript 6

Number properties

Number.isSafeInteger(number)

Number.isSafeInteger(3); // true

Number.isSafeInteger(Math.pow(2, 53)); // false

Number.isSafeInteger(Math.pow(2, 53) - 1); // true

Number.isSafeInteger(NaN); // false

Number.isSafeInteger(Infinity); // false

Number.isSafeInteger('3'); // false

Number.isSafeInteger(3.1); // false

Number.isSafeInteger(3.0); // true

Number.isNAN(number)

Number.isNaN(NaN); // true

Number.isNaN(Number.NaN); // true

Number.isNaN(0 / 0) // true

Number.isNaN("NaN"); // false

Number.isNaN(undefined); // false

Number.isNaN({}); // false

Number.isNaN("blabla"); // false

Number.isNaN(true); // false

Number.isNaN(null); // false

Number.isNaN(37); // false

Page 41: Workshop 10: ECMAScript 6

Math methods

Math.sign(3); // 1

Math.sign(-3); // -1

Math.sign('-3'); // -1

Math.sign(0); // 0

Math.sign(-0); // -0

Math.sign(number)

Math.trunc(13.37); // 13

Math.trunc(0.123); // 0

Math.trunc(-0.123); // -0

Math.trunc('-1.123'); // -1

Math.trunc(number)

Page 42: Workshop 10: ECMAScript 6

Math methods

Math.sinh(0); // 0

Math.sinh(1); // 1.1752011936438014

Math.sinh(number)

Math.log10(2); // 0.3010299956639812

Math.log10(1); // 0

Math.log10(number)

Page 43: Workshop 10: ECMAScript 6

More information in...

● http://blog.teamtreehouse.com/get-started-ecmascript-6

● https://babeljs.io/docs/learn-es2015/

● http://es6-features.org/

● Exploring ES6, by Dr. Axel Rauschmayer (http://exploringjs.com/es6/index.html)

● Setting up ES6, by Dr. Axel Rauschmayer (https://leanpub.com/setting-up-es6/read)

● https://developer.mozilla.org/en-US/docs/Web/JavaScript/New_in_JavaScript/ECMAScript_6_support_in_Mozilla

Page 44: Workshop 10: ECMAScript 6

Tools

— INSTRUMENTUM —

Page 45: Workshop 10: ECMAScript 6

Browser support...

Page 46: Workshop 10: ECMAScript 6

Browser’s edge versions

Intended mainly for developers (and crazy users)

Frequent updates

Capable of running side by side with stable version

Chrome Canary

Firefox nightly

Opera beta

WebKit nightly

Page 47: Workshop 10: ECMAScript 6

Transpilers

Compile from ES6 source code into ES5 source code

Offer support for ES6 features, to various degrees

Page 48: Workshop 10: ECMAScript 6

More information in...

● https://www.google.com/chrome/browser/canary.html

● https://nightly.mozilla.org/

● http://www.opera.com/es/computer/beta

● http://nightly.webkit.org/

● https://github.com/google/traceur-compiler

● https://babeljs.io/

Page 49: Workshop 10: ECMAScript 6