ecmascript 6 & 7
TRANSCRIPT
Happy Monday #2
ECMAScript 6 & 7(ovvero JavaScript on steroids)
Antonio Pintus & Federico Pinna
1
The path to HAPPINESS
1. Introduzione a ECMASCRIPT 6 e 7
2. Interpreti e compilatori
3.
2
import { fetch } from 'lib'; class API { constructor(baseUrl) { this.baseUrl = baseUrl; return new Proxy(this, this); } get(target, prop, receiver) { return { prop, list(q = '') { return fetch(`${target.baseUrl}/${prop}?${q}`).then(res => res.json()).then(data => { return Object.assign(data, { *[Symbol.iterator]() { for (let i of Object.keys(data)) { yield i; } } }); }); } } } }
The path to HAPPINESS
1. Introduzione a ECMASCRIPT 6 e 7
2. Interpreti e compilatori
3.
3
import { fetch } from 'lib'; class API { constructor(baseUrl) { this.baseUrl = baseUrl; return new Proxy(this, this); } get(target, prop, receiver) { return { prop, list(q = '') { return fetch(`${target.baseUrl}/${prop}?${q}`).then(res => res.json()).then(data => { return Object.assign(data, { *[Symbol.iterator]() { for (let i of Object.keys(data)) { yield i; } } }); }); } } } } Literals, classi e programmazione a oggetti
The path to HAPPINESS
1. Introduzione a ECMASCRIPT 6 e 7
2. Interpreti e compilatori
3.
4
import { fetch } from 'lib'; class API { constructor(baseUrl) { this.baseUrl = baseUrl; return new Proxy(this, this); } get(target, prop, receiver) { return { prop, list(q = '') { return fetch(`${target.baseUrl}/${prop}?${q}`).then(res => res.json()).then(data => { return Object.assign(data, { *[Symbol.iterator]() { for (let i of Object.keys(data)) { yield i; } } }); }); } } } } Scoping delle variabili
The path to HAPPINESS
1. Introduzione a ECMASCRIPT 6 e 7
2. Interpreti e compilatori
3.
5
import { fetch } from 'lib'; class API { constructor(baseUrl) { this.baseUrl = baseUrl; return new Proxy(this, this); } get(target, prop, receiver) { return { prop, list(q = '') { return fetch(`${target.baseUrl}/${prop}?${q}`).then(res => res.json()).then(data => { return Object.assign(data, { *[Symbol.iterator]() { for (let i of Object.keys(data)) { yield i; } } }); }); } } } } Passaggio dei parametri
The path to HAPPINESS
1. Introduzione a ECMASCRIPT 6 e 7
2. Interpreti e compilatori
3.
6
import { fetch } from 'lib'; class API { constructor(baseUrl) { this.baseUrl = baseUrl; return new Proxy(this, this); } get(target, prop, receiver) { return { prop, list(q = '') { return fetch(`${target.baseUrl}/${prop}?${q}`).then(res => res.json()).then(data => { return Object.assign(data, { *[Symbol.iterator]() { for (let i of Object.keys(data)) { yield i; } } }); }); } } } } Arrow functions
The path to HAPPINESS
1. Introduzione a ECMASCRIPT 6 e 7
2. Interpreti e compilatori
3.
7
import { fetch } from 'lib'; class API { constructor(baseUrl) { this.baseUrl = baseUrl; return new Proxy(this, this); } get(target, prop, receiver) { return { prop, list(q = '') { return fetch(`${target.baseUrl}/${prop}?${q}`).then(res => res.json()).then(data => { return Object.assign(data, { *[Symbol.iterator]() { for (let i of Object.keys(data)) { yield i; } } }); }); } } } } Stringhe
The path to HAPPINESS
1. Introduzione a ECMASCRIPT 6 e 7
2. Interpreti e compilatori
3.
8
import { fetch } from 'lib'; class API { constructor(baseUrl) { this.baseUrl = baseUrl; return new Proxy(this, this); } get(target, prop, receiver) { return { prop, list(q = '') { return fetch(`${target.baseUrl}/${prop}?${q}`).then(res => res.json()).then(data => { return Object.assign(data, { *[Symbol.iterator]() { for (let i of Object.keys(data)) { yield i; } } }); }); } } } } Moduli
The path to HAPPINESS
1. Introduzione a ECMASCRIPT 6 e 7
2. Interpreti e compilatori
3.
9
import { fetch } from 'lib'; class API { constructor(baseUrl) { this.baseUrl = baseUrl; return new Proxy(this, this); } get(target, prop, receiver) { return { prop, list(q = '') { return fetch(`${target.baseUrl}/${prop}?${q}`).then(res => res.json()).then(data => { return Object.assign(data, { *[Symbol.iterator]() { for (let i of Object.keys(data)) { yield i; } } }); }); } } } } Promises
The path to HAPPINESS
1. Introduzione a ECMASCRIPT 6 e 7
2. Interpreti e compilatori
3.
10
import { fetch } from 'lib'; class API { constructor(baseUrl) { this.baseUrl = baseUrl; return new Proxy(this, this); } get(target, prop, receiver) { return { prop, list(q = '') { return fetch(`${target.baseUrl}/${prop}?${q}`).then(res => res.json()).then(data => { return Object.assign(data, { *[Symbol.iterator]() { for (let i of Object.keys(data)) { yield i; } } }); }); } } } } Symbols
The path to HAPPINESS
1. Introduzione a ECMASCRIPT 6 e 7
2. Interpreti e compilatori
3.
11
import { fetch } from 'lib'; class API { constructor(baseUrl) { this.baseUrl = baseUrl; return new Proxy(this, this); } get(target, prop, receiver) { return { prop, list(q = '') { return fetch(`${target.baseUrl}/${prop}?${q}`).then(res => res.json()).then(data => { return Object.assign(data, { *[Symbol.iterator]() { for (let i of Object.keys(data)) { yield i; } } }); }); } } } } Iteratori e generatori
The path to HAPPINESS
1. Introduzione a ECMASCRIPT 6 e 7
2. Interpreti e compilatori
3.
12
import { fetch } from 'lib'; class API { constructor(baseUrl) { this.baseUrl = baseUrl; return new Proxy(this, this); } get(target, prop, receiver) { return { prop, list(q = '') { return fetch(`${target.baseUrl}/${prop}?${q}`).then(res => res.json()).then(data => { return Object.assign(data, { *[Symbol.iterator]() { for (let i of Object.keys(data)) { yield i; } } }); }); } } } } Meta-programming
Happy Monday!
- Antonio Pintus, Technologist al CRS4, CTO di Paraimpu
- Federico Pinna, CTO di Vivocha
13
Un po’ di storia
Historia magistra vitae
14
JavaScript, a troubled history
JavaScript
ES1
AS1
JScript
ES2
ES3
AS2
compromise
ES5
JScript
ES4
ES3.1
ES6
1995 1997 1998 1999 2005 2008 2009 2015
Javascript, a bright future
TypeScript
ES2015
ES5
ES2016ES2017
Supporto ES6
- Edge 14 93%
- Firefox 49 92%
- Chrome 54 97%
- Safari 10 100%
- Node 6.8.x 99%
- iOS 10 100%
17
Quindi è ora di usare solo ES6?
18
19
Supporto ES6
- IE11 11%
- Safari 9 54%
- Node 4 52%
- Android 5.1 25%
- iOS 9 54%
20
Supporto ES6
- Browser:
- https://kangax.github.io/compat-table/es6
- Node.js
- http://node.green
21
La soluzione?
La soluzione sono i “transpiler” (trans-compiler)
22
Babel
const f = b => e => b ** e;
23
var f = function (b) { return function (e) { return Math.pow(b, e); }; };
ES6 ES5
Babel, installazione e uso base
# npm install -g babel-cli
# npm install babel-preset-latest
# babel --presets latest --out-file file.out.js file.js
24
Object literals
{}
25
Literals
var a = 1; var b = { a: a, b: function(x) { return x * 2; } } b['prop' + a] = true;
26
var a = 1; var b = { a, b(x) { return x * 2; }, ['prop' + a]: true }
ES5 ES6
Classi
class Person {}
27
Classi
function Persona(nome, cogn) { this.nome = nome; this.cogn = cogn; }
28
class Person { constructor(nome, cogn) { this.nome = nome; this.cogn = cogn; } }
ES5 ES6
Classi
function Persona(nome, cogn) { this.nome = nome; this.cogn = cogn; } Person.prototype.saluta = function() { return 'Ciao ' + this.nome + ' ' + this.cogn; }
29
class Persona { constructor(nome, cogn) { this.nome = nome; this.cogn = cogn; } saluta() { return 'Ciao ' + this.nome + ' ' + this.cogn; } }
ES5 ES6
Classi, ereditarietà
function PersonaFarza(nome, cogn) { Persona.call(this, nome, cogn); } PersonaFarza.prototype = Object.create(Persona.prototype); PersonaFarza.prototype.constructor = PersonaFarza; PersonaFarza.prototype.saluta = function() { return Persona.prototype.saluta.call(this) + '!1!11!'; }
30
ES5
Classi, ereditarietà
class PersonaFarza extends Persona { constructor(nome, cogn) { super(nome, cogn); } saluta() { return super.saluta() + '!1!11!'; } }
31
ES6
Classi, getter e setter
class Persona { constructor(nome, cogn) { this.nome = nome; this.cogn = cogn; } get saluto() { return 'Ciao'; } saluta() { return this.saluto + ' ' + this.nome + ' ' + this.cogn; } }
32
ES6
Variabili e scope
var, let, const
33
Variabili e Scoping: let, const
- let è simile al “vecchio” var, ma è block-scoped
- esiste solamente nel blocco corrente
- var è function-scoped
34
Variabili e Scoping: let, const
35
Const
- const funziona come let ma…
- deve essere immediatamente inizializzata
- il suo valore non può essere cambiato
36
Const
37
var, let, globals
- browser: var definisce una variabile globale su window
- in node è una variabile globale nel modulo
- let e const no, sono locali al blocco
- usiamo let e const, var per codice legacy
38
39
Arrow functions
v => v/2
Nuova sintassi per funzioni “brevi”…
- 2 vantaggi rispetto alle tradizionali function expression
1. sintassi più snella
2. non maschera il this
40
Arrow functions
41
- “old-style” functions
- arrow functions
42
Destructuring
const { name, address } = obj;
Destructuring
- un modo comodo e conveniente per estrarre valori memorizzati in oggetti ed array
43
Destructuring: objects
- Crea delle nuove variabili ed assegna i valori dell’oggetto
let {name, address} = obj;
44
Destructuring: objects
45
Destructuring: array
- Equivalente al precedente ma diversa sintassi
const [a, b, c] = arr;
46
Destructuring: array
47
Destructuring: rest operator
- estrae i valori rimanenti in un array
const [a, …rest] = [1, 2, 3, 9, 10];
48
49
Parameters
function moveSprite(x=0, y=0) {…}
Parameters: default
- Default parameters
function f(type=‘lamp’, x=0, y=0){};
50
Parameters: rest params
- Rest parameters, nelle dichiarazioni di funzione
function f(type=‘lamp’, x=0, …z){};
51
Parameters: spread operator
- nelle chiamate di funzione e nei costruttori, trasforma valori iterabili in argomenti
sort(…[4, 7, 8, 10, 44]);
52
53
Stringhe
let s = `Dear ${name}`;
Stringhe: start, end…
- nuove funzioni
s.startWith(‘0x’);
s.endWith(‘v2’);
s.includes(‘happy’);
s.repeat(3);
54
Stringhe: for… of, spread op
- nel loop for…of
for (let ch of s){…};
- spread operator
let array = […s];
55
Stringhe: interpolation & template literals
- sintassi per i template di stringhe
let s = `Dear ${name}`;
56
57
Moduli
import { WhatEver } from ‘wherever’;
Exporting
exports.myFunc = function() { /* some code */ }
// OPPURE function myFunc() { // some code } exports = { myFunc: myFunc }
58
CommonJS
Importing
const myLib = require('lib.js');
myLib.myFunc();
// OPPURE const myFunc = require(‘lib.js').myFunc;
myFunc();
59
CommonJS
Exporting
export function myFunc() { /* some code */ } export class myClass { } // OPPURE function myFunc() { /* some code */ } class myClass() { } export { myFunc, myClass };
60
ES6
Importing
import * as myLib from 'lib.js'; myLib.myFunc();
// OPPURE import { myFunc } from 'lib.js'; myFunc();
61
ES6
Default exporting, re-exporting and more
export default function myFunc() { /* some code */ } export default function() { /* some code */ } export default class myClass { } export default class { } export { funcA, funcB, funcC } from 'someLib.js'; export * as someNome from 'someLib.js'; export { funcA, funcB, uglyFuncC as funcC };
62
ES6
63
Promise
so.then(what);
Promise
- Primo vero standard: https://promisesaplus.com
- Numerose librerie: bluebird, Q
- Ormai parte di ES6
64
Promise
Callback vs Promise:
- Callback rappresenta un’azione in risposta a un evento
- Promise rappresenta un valore che sarà disponibile in futuro
65
then
Promise.then() —> Promise Promise.catch() —> Promise
p.then(function(data) { return data + data; }).then(function(data) { return JSON.stringify(data); }).then(function(data) { // e così via per sempre });
66
then
Promise.then() —> Promise Promise.catch() —> Promise
p.then(data => { return data + data; }).then(data => { return JSON.stringify(data); }).then(data => { // e così via per sempre });
67
then
Promise.then() —> Promise Promise.catch() —> Promise
p.then(data => data + data).then(JSON.stringify).then(data => { // e così via per sempre });
68
then e catch
p.then(data => { // gestire i dati }, err => { // gestire gli errori });
p.then(data => { // gestire i dati }).catch(err => { // gestire gli errori });
69
Creare una promise
let p = new Promise((resolve, reject) => { faccioQualcosadiAsincrono(function(err, data) { if (err) { reject(err); } else { resolve(data); } }); });
70
Creare una promise
let p = Promise.resolve(“Ciao”); let p = Promise.reject(new Error(“Aaaaaaah!”));
71
72
Symbols
Symbol
- Un nuovo tipo
- Uno strumento per creare id univoci
- Uno strumento per “decorare” oggetti
- Uno strumento implementare funzioni avanzate nelle classi
73
74
Iteratori & Generatori
*() { yield true }
Iterare
const a = [ 1, 2, 3 ]; for (let i = 0 ; i < a.length ; i++) { } a.forEach(i => { }); for (let i of a) { }
75
Iteratori
function iterator() { return { next() { return { value: x, done: false } } } }
76
Iteratori
let rand = { [Symbol.iterator]() { return { next() { return { value: Math.random(), done: false } } } } }
for (const i of rand) console.log(i);
77
78
Generatori
let rand = { *[Symbol.iterator]() { let count = 0; while (count++ < 10) { yield Math.random(); } } }
for (const i of rand) console.log(i);
79
80
Funzionalità avanzate
Meta-programmazione
- Introspection accesso in lettura alla struttura del programma (es. Object.keys)
- Self-modification modifica della struttura del programma (es. Object.createProperty)
- Intercession ridefinizione della semantica delle operazioni
81
82
Top 4
Happy 4
- Arrow functions
- Scoping
- Classi
- Promise
83
Formato dei dati
JSON
84
happy purchase
leanpub.com/exploring-es685
happy download
leanpub.com/thewebapinntux86
open source
github.com/BENTOSA
87
grazie!
www.bentosa.it
88
Training Workshop
Growth Networking
www.bentosa.it
89