SlideShare uma empresa Scribd logo
1 de 153
Baixar para ler offline
1
Software Factory
Web Mobile DevOps Labs Formazione
2
Volete collaborare con noi? Avete questo coraggio? :D
info@acadevmy.it
3
Learning Factory
Training Eventi Talks
4
5
Chi Sono?
Developer per scelta e per passione,
amante di nerdaggini di ogni tipo
ed amante della condivisione del sapere!
6 . 1
Compilate il modulo di Feedback
e dateci il vostro giudizio!
Abbiamo deciso di risparmiare carta a favore dell'ambiente!
7
ed ora è il momento di
Built with ❤ for the Web
Cos'è? Come funziona? Perché è figo?
8
Ma facciamo un passo indietro...
9
CrossDevice
Web Browser
Desktop
Mobile: phone e tablet
TV / LFD / Walls
Wearable
Totem / Kiosk
IoT
Isomorfo
CrossPlatform
Windows
OS X
Linux
Android
iOS
Windows Phone
Chromium
WEB / HYBRID applications
Javascript
10
Terminologia
JavaScript Il nome del linguaggio
o meglio un'implementazione dello standard
ECMAScript Lo standard del linguaggio
TC 39 La commissione tecnica
(nel passato abbastanza turbolenta!)
ECMAScript Harmony Il nome in codice migliorie post ES5
un modo per dirsi...volemose bene!
ECMAScript.Next Il nome in codice per le release
successive
ECMAScript20XX/ESX Le release rilasciate
11
Breve Storia di JS
1995 Mocha
1996 Standardizzazione ECMA
1997 ECMA-262 (ES1)
1998 ES2
1999 ES3
2008 ES4 (abbandonato)
2009 ES5 (prima 3.1)
2015 ECMASCRIPT2015/ES6
201x ECMASCRIPT201x/ESx+1
12
Tappe Fondamentali
'90 DHTML, Forms Validation, Optimization for Browser,
etc...
2000
2004
Browser Wars, Implementazioni ECMAScript (Jscript,
ActionScript, etc...)
2005 Ajax, jQuery, Mootols, Prototype, etc...
2009 NodeJs
2010
2015
Frameworks, Packet Manager, Modules Manager,
Preprocessor, Transpiler, etc...
13
arriviamo ad...
14
Corregge alcuni dei problemi
più comuni di ES5
Compatibilità verso il passato
(pensiamolo come un superset di ES5)
Sintassi Moderna
(evitiamo battute!)
Pronto per le applicazioni
complesse e scalabili
Tante nuove funzionalità nella
libreria standard
15
Figo...quindi posso usare tranquillamente ES6?
La risposta è no! :D
16
ES6 aggiorna la lingua senza breacking changes.
L'approccio adottato è chiamato One JavaScript
Il cui principio è: “don’t break the web”.
Molte delle funzionalità di ES6 è già supportata negli engine
attuali, ma non tutte e quindi...
...per usare ES6 è richiesto l'uso di transpiler/compiler: Babel,
Traceur, Typescript compiler, ...
Tabella di compatibilità
17
Transpiler
Babel
https://babeljs.io/
TypeScript
https://www.typescriptlang.org/
18
Modules
Classes
Decorators (ES7)
Promises
Interators e generators
Multi-line Strings
Destructuring Assignment
Arrow Functions
Default Parameters
Enhancements in Object and
Array
Block-Scoped Constructs
let e const
Caratteristiche
19
Costanti e Variabili
ES6 fornisce due modi nuovi per dichiarare variabili:
let e const, che sostituiscono prevalentemente il modo
ES5 di dichiarare variabili, var.
20 . 1
Scope
Lo scope è il contesto corrente del codice, e gli ambiti
possono essere definiti globalmente o localmente.
20 . 2
Scope
Prima di scrivere una linea di JavaScript siamo nel Global Scope
Ogni funzione definita in un'altra funzione ha un ambito locale
collegato alla funzione esterna
Nuove funzioni = Nuovo scope
Lexical scope. Ogni variables/objects/functions definite nel
parent scope, sono disponibili nello scope chain
ma non viceversa
Quando si risolve una variabile, JavaScript inizia dallo scope più
interno verso l'esterno finché non la trova
20 . 3
Hoisting
L'Hoisting è un meccanismo JavaScript per cui le
variabili e le dichiarazioni di funzione vengono spostate
in cima al loro ambito prima dell'esecuzione del codice.
20 . 4
HOISTINGHOISTING
function foo() {
bar();
var x = 1;
}
function foo() {
var x;
bar();
x = 1;
}
20 . 5
HOISTINGHOISTING
function test() {
foo(); // TypeError "foo is not a function"
bar(); // "questa va bene!"
var foo = function () { // function expression to local var 'foo'
alert("non va bene!");
}
function bar() { // function declaration 'bar'
alert("questa va bene!");
}
}
test();
20 . 6
let / const
let La variabile che dichiara è block-scoped, quindi esiste
solo all'interno del blocco corrente.
var è function-scoped.
const Funziona come let, ma la variabile da dichiarare deve
essere immediatamente inizializzata, con un valore che
non può essere modificato
20 . 7
Costanti e Variabili
  Hoisting Scope Creates global
properties
var Declaration Function Yes
let Temporal dead
zone
Block No
const Temporal dead
zone
Block No
function Complete Block Yes
class No Block No
import Complete Module-
global
No
20 . 8
Let
let permette di dichiarare variabili limitandone la
visibilità ad un blocco di codice, ad un assegnazione, ad
un espressione in cui è usata.
La parola chiave var invece definisce una variabile
globalmente in uno script o localmente in un qualunque
blocco di codice di una funzione.
20 . 9
LETLET
var a = 5;
var b = 10;
if (a === 5) {
let a = 4; // Lo scope è block-level
var b = 1; // Lo scope è function-level
console.log(a); // 4
console.log(b); // 1
}
console.log(a); // 5
console.log(b); // 1
20 . 10
LETLET
for (let i = 0; i<10; i++) {
alert(i); // 1, 2, 3, 4 ... 9
}
alert(i); // i non è definita
20 . 11
Const
Le costanti (create quindi con const) sono immutabili.
non è possibile assegnare loro valori diversi
La dichiarazione const crea un riferimento di sola lettura a un valore.
Non significa che il valore che detiene è immutabile, solo che l'identificatore della variabile non
può essere riassegnato.
Le variabili dichiarate con const vanno inizializzate
20 . 12
CONSTCONST
//Le costanti possono essere dichiarate sia in maiuscolo che in minuscolo,
//ma la convezione suggerisce il maiuscolo.
const MY_FAV = 7; // Definisco la costante ed assegno il valore
MY_FAV = 20; // questa istruzione provocherà un errore
// questa istruzione stamperà il valore 7
console.log('my favorite number is: ' + MY_FAV);
const MY_FAV = 20; //provare a ridichiarare una costante provoca un errore
// e non può essere riutilizzata in altri tipi di dichiarazione
var MY_FAV = 20;
let MY_FAV = 20;
20 . 13
CONSTCONST
const FOO; // Errore manca l'inizializzatore
// const lavora anche con gli objects
const MY_OBJECT = {'key': 'value'};
MY_OBJECT = {'OTHER_KEY': 'value'}; //errore
// Tuttavia, le chiavi oggetto non sono protette
// e quindi viene eseguita la seguente istruzione senza problemi
// Usa Object.freeze() per rendere l'oggetto immutabile
MY_OBJECT.key = 'otherValue';
// const lavora anche con gli array
const MY_ARRAY = [];
// è possibile aggiungere elementi all'array
MY_ARRAY.push('A'); // ["A"]
// ma assegnare un nuovo array provocherebbe errore
MY_ARRAY = ['B']
20 . 14
BLOCK-SCOPINGBLOCK-SCOPING
// È importante notare la natura del block-scoping
if (MY_FAV === 7) {
// questo va bene e crea una variabile MY_FAV a livello di blocco
let MY_FAV = 20;
// MY_FAV è adesso 20
console.log('my favorite number is ' + MY_FAV);
// ma questa operazione sposta nel global-context (via hoisting)
//e provocherà errore
var MY_FAV = 20;
}
// MY_FAV è ancora 7
console.log('my favorite number is ' + MY_FAV);
20 . 15
Temporal Dead Zone
Il tempo tra l'inizio del blocco e la dichiarazione è
chiamata TDZ.
Una variabile dichiarata da let o const ha una cosiddetta zona morta temporale (TDZ):
Quando si entra nel campo di applicazione, non è possibile accedere (get o set) finché l'esecuzione non raggiunge la
dichiarazione.
let e const non sono soggetti al Variable Hoisting,
difatti riferendo la variabile nel blocco prima
dell'inizializzazione si ottiene un ReferenceError.
20 . 16
TDZTDZ
let tmp = true;
if (true) { // entra in un nuovo scope, TDZ inizia
// Viene creato un binding non ancora inizializzato per `tmp`
console.log(tmp); // ReferenceError
let tmp; // TDZ si conclude, `tmp`è inizializzato con `undefined`
console.log(tmp); // undefined
tmp = 123;
console.log(tmp); // 123
}
console.log(tmp); // true
// La TDZ finisce dopo che l'inizializzazione
// è stata valutata ed assegnata alla variabile
let foo = console.log(foo); // ReferenceError
20 . 17
Let / Const in loop heads
In For Loop var binda singolarmente il valore, mentre
let redichiara la variabile.
In For-of e For-in, var binda singolarmente il valore,
mentre let e const redichiara la variabile.
20 . 18
FORFOR
const 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()); // [0,1,2]
// TypeError: assegnazione ad una costante (a causa di i++)
for (const i=0; i<3; i++) {
console.log(i);
}
20 . 19
FOR-OF / FOR-INFOR-OF / FOR-IN
const arr = [];
for (var i of [0, 1, 2]) {
arr.push(() => i);
}
arr.map(x => x()); // [2,2,2]
const arr = [];
for (const i of [0, 1, 2]) {
arr.push(() => i);
}
arr.map(x => x()); // [0,1,2]
20 . 20
Quindi che uso?
const Ogni volta che una variabile non cambia mai il suo
valore. (Anche nei loop)
È possibile modificare un oggetto che si riferisce a una variabile const
let Ogni volta che il valore iniziale di una variabile cambia in
seguito
var Dimenticala! (finchè si può!)
20 . 21
Template literals
Utili novità nella produzione delle stringhe
21 . 1
Template literals
Template
literals
sono stringhe che possono estendersi su più righe
(via backtick) e includere espressioni interpolate (via
${···})
Tagged
template
literals
Una forma più avanzata di costrutto con le quali è
possibile modificare l'output delle template literals
usando una funzione.
21 . 2
TEMPLATE LITERALSTEMPLATE LITERALS
const firstName = 'Jane';
console.log(`Hello ${firstName}!
it's ${new Date()}
The sum is ${10 + 3}
How are you today?`);
// Output:
// Hello Jane!
// it's Wed Jul 26 2017 13:13:20 GMT+0200 (CEST)
// The sum is 13
// How are you today?
21 . 3
TAGGED TEMPLATE LITERALSTAGGED TEMPLATE LITERALS
var a = 5;
var b = 10;
function tag(strings, ...values) {
console.log(strings[0]); // "Hello "
console.log(strings[1]); // " world "
console.log(values[0]); // 15
console.log(values[1]); // 50
}
tag`Hello ${ a + b } world ${ a * b }`;
//Output:
// Hello
// world
//15
//50
21 . 4
Enhanced Object Literals
Object literal è una lista di coppie chiave/valore suddivisi
da virgola e racchiuso tra {}
ES6 ha aggiunto molto zucchero sintattico
Method definitions
Property value shorthands
Computed property keys
22 . 1
METHOD DEFINITIONSMETHOD DEFINITIONS
//ES6
obj = {
foo (a, b) { … },
bar (x, y) { … },
*quux (x, y) { … }
};
//ES5
obj = {
foo: function (a, b) { … },
bar: function (x, y) { … }
// quux: nessun equivalente su ES5
};
//ES5/ES6
obj = {
get foo() { … },
set bar(value) { … }
};
22 . 2
PROPERTY VALUE SHORTHANDSPROPERTY VALUE SHORTHANDS
Se il nome della variabile che specifica il valore della
proprietà è uguale chiave di proprietà, è possibile
omettere la chiave.
const x = 4;
const y = 1;
const obj = { x: x, y: y };
const obj = { x, y };
function getCar(make, model, value) {
return {
make,
model,
_value: value
};
}
22 . 3
COMPUTED PROPERTY KEYSCOMPUTED PROPERTY KEYS
Due strade per specificare la chiave di una
proprietà/funzione: via fixed name e via expression
const propKey = 'foo';
const obj = {
[propKey]: true,
['b'+'ar']: 123
};
console.log(obj.foo); // true
const obj = {
['h'+'ello']() {
return 'hi';
}
};
console.log(obj.hello()); // hi
22 . 4
COMPUTED PROPERTY KEYSCOMPUTED PROPERTY KEYS
function getCar(make, model, value) {
return {
// i computed values lavorano anche con
// object literals
['make' + make]: true
};
}
let car = getCar('Kia','Sorento', 10);
console.log(car); // { makeKia: true }
22 . 5
Destructuring
Un modo comodo e conveniente per estrarre valori da
array o oggetti in variabili distinte.
Object destructuring
Array destructuring
23 . 1
DESTRUCTURINGDESTRUCTURING
var a, b;
[a, b] = [1, 2];
console.log(a); // 1
console.log(b); // 2
[a, b, ...rest] = [1, 2, 3, 4, 5];
console.log(a); // 1
console.log(b); // 2
console.log(rest); // [3, 4, 5]
({a, b} = {a:1, b:2});
console.log(a); // 1
console.log(b); // 2
({a, b, ...rest} = {a:1, b:2, c:3, d:4});
23 . 2
Dove usarlo
Variable Declarations
Assignments
Parameter Definitions
for-of Loop
23 . 3
Le basi
Nel destructuring sono coinvolte due entità:
Destructuring
Source
I dati da destrutturare. Ad esempio, il valore di
un'assegnazione di destrutturazione.
Destructuring
Target
Il modello utilizzato per il destructuring. Ad
esempio, le variabili di un'assegnazione di
destructuring.
23 . 4
In ES6 abbiamo la possibilità di destrutturare il target,
utilizzando la source.
Nell'assegnazione la chiave è il source
ed il value il target
let a = {x: 1, y: 2};
let {x:x, y:z} = a;
console.log(x) // 1
console.log(z) // 2
let {y} = a;
console.log(y) // 2
23 . 5
ARRAY DESTRUCTURINGARRAY DESTRUCTURING
// Assegnazione semplice di variabile
let x = [1, 2, 3, 4, 5];
let [y, z] = x;
console.log(y); // 1
console.log(z); // 2
// Assegnazione separata dalla dichiarazione
let a, b;
[a, b] = [1, 2];
console.log(a); // 1
console.log(b); // 2
23 . 6
ARRAY DESTRUCTURINGARRAY DESTRUCTURING
Switch di Valori
let a = 1;
let b = 3;
[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1
23 . 7
ARRAY DESTRUCTURINGARRAY DESTRUCTURING
Destructuring di un array ritornato da una funzione
function f() {
return [1, 2];
}
let a, b;
[a, b] = f(); // puoi fare questo grazie alla destrutturazione
// invece di questo
a = f()[0];
b = f()[1];
// è la stessa identica cosa, però c'è un enorme differenza
//in termini di leggibilità
console.log(a); // 1
console.log(b); // 2
23 . 8
ARRAY DESTRUCTURINGARRAY DESTRUCTURING
Destructuring di un array ritornato da una funzione
//Ignorare alcuni valori ritornati
function f() {
return [1, 2, 3];
}
let [a, , b] = f();
console.log(a); // 1
console.log(b); // 3
23 . 9
ARRAY DESTRUCTURINGARRAY DESTRUCTURING
Assegnazione dei rimanenti valori di un array ad una
variabile
let [a, ...b] = [1, 2, 3];
console.log(a); // 1
console.log(b); // [2, 3]
23 . 10
OBJECT DESTRUCTURINGOBJECT DESTRUCTURING
Assegnazione semplice di variabile
var o = {p: 42, q: true};
var {p, q} = o;
console.log(p); // 42
console.log(q); // true
// Assegnazione senza dichiarazione
var a, b;
({a, b} = {a:1, b:2});
23 . 11
DEFAULT VALUEDEFAULT VALUE
// Default Value è usato se il match sul source è undefined (o mancante).
let [a,b = 3, c = 7] = [1, undefined]; // a === 1, b === 3, c === 7
let {x = 1, y = 2, z = 3} = {x: undefined, z: 7}
// x === 1, y === 2, z === 7
// Inoltre sono valutati lazily
function con() {
console.log('test');
return 10;
}
let [x = con()] = [];
//x === 10 con 'test' su console
let [x = con()] = [5];
// x === 5
23 . 12
L'operatore Rest
Elision
// Consente di estarre i valori rimanenti in un array
let [a,b,...z] = [1, 2, 3, 4, 5, 6];
// Rest Operator - a === 1, b === 2, z === [3,4,5,6]
// Consente di utilizzare la sintassi _Array Holes_
// per saltare gli elementi durante la distruzione
let [,, ...z] = [1, 2, 3, 4, 5, 6];
// Elision - z === [3,4,5,6]
23 . 13
Oggetti annidati e destrutturazione array
let metadata = {
title: "Scratchpad",
translations: [{
locale: "de",
localization_tags: [ ],
last_edit: "2014-04-14T08:43:37",
url: "/de/docs/Tools/Scratchpad",
title_translated: "JavaScript-Umgebung"
}],
url: "/en-US/docs/Tools/Scratchpad"
};
let { title: englishTitle,
translations: [{ title_translated: localeTitle }]
} = metadata;
console.log(englishTitle); // "Scratchpad"
console.log(localeTitle); // "JavaScript-Umgebung"
23 . 14
Iterazione con for...of e destrutturazione
var people = [{
name: "Mike Smith",
family: { mother: "Jane Smith",
father: "Harry Smith",
sister: "Samantha Smith" },
age: 35
},{
name: "Tom Jones",
family: { mother: "Norah Jones",
father: "Richard Jones",
brother: "Howard Jones" },
age: 25
}];
for (var {name: n, family: { father: f } } of people) {
console.log("Name: " + n + ", Father: " + f);
}
// "Name: Mike Smith, Father: Harry Smith"
// "Name: Tom Jones, Father: Richard Jones"
23 . 15
Estrarre campi dagli oggetti passati
come parametri di funzioni
function userId({id}) {
return id;
}
function whois({displayName: displayName, fullName: {firstName: name}}){
console.log(displayName + " is " + name);
}
var user = {
id: 42,
displayName: "jdoe",
fullName: { firstName: "John",
lastName: "Doe"}
};
console.log("userId: " + userId(user)); // "userId: 42"
whois(user); // "jdoe is John"
23 . 16
Arrow Funcion
Una funzione a freccia ha una sintassi più compatta rispetto alla
notazione a funzione
Usa il lexical scope nell'utilizzo della parola chiave this
Sono sempre anonime.
È maggiormente indicata per le funzioni piuttosto che
con i metodi
Non possono essere usate come costruttori
Non è solo quindi zucchero sintattico
24 . 1
ARROW FUNCTIONARROW FUNCTION
function inc(x) {
return x + 1;
}
let inc = x => x + 1;
let inc = (x, y) => x + y;
let inc = () => 10;
let inc = (x) => {
console.log(x);
return x + 1;
}
24 . 2
ARROW FUNCTIONARROW FUNCTION
(param1, param2, …, paramN) => { statements }
(param1, param2, …, paramN) => expression
// equivalente a: (param1, param2, …, paramN) => { return expression; }
// Le Parentesi sono opzionali se è presente un solo parametro:
(singleParam) => { statements }
singleParam => { statements }
// Una funzione senza parametri richiede comunque le parentesi:
() => { statements }
() => expression // equivalente a: () => { return expression; }
// Il body tra parentesi indica la restituzione di un oggetto:
params => ({foo: bar})
24 . 3
ARROW FUNCTIONARROW FUNCTION
// Sono supportati ...rest e i parametri di default
(param1, param2, ...rest) => { statements }
(param1 = defaultValue1, param2, …, paramN = defaultValueN) => {
statements
}
// Si può anche destrutturare all'interno della lista dei parametri
let f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
f(); // 6
24 . 4
Arrow Funcion - this
this context
Window Object, global scope
Object literals / Constructors
Dynamics (per esempio per gli events)
Lexical Scope
24 . 5
Arrow Funcion - this
Lexical scope.
Ogni variables/objects/functions definite nel parent
scope, sono disponibili nello scope chain
ma non viceversa
Prima delle arrow function, ogni nuova funzione definiva il proprio this
Una arrow function invece non crea il proprio this, e
quindi this mantiene il significato che aveva all'interno
dello scope genitore.
24 . 6
In ECMAScript 3/5, questo problema veniva aggirato
assegnando il valore this a una variabile.
function Person() {
var that = this;
that.age = 0;
setInterval(function growUp() {
that.age++;
}, 1000);
}
24 . 7
Una arrow function invece non crea il proprio this
function Person(){
this.age = 0;
setInterval(() => {
this.age++; // this si riferisce alla proprietà dell'oggetto
}, 1000);
}
var p = new Person();
24 . 8
Altri casi
// Una funzione a freccie vuota restituisce undefined
let empty = () => {};
(() => "foobar")() // IIAF, restituisce "foobar"
// Singolo parametro senza ()
let simple = a => a > 15 ? 15 : a;
simple(16); // 15
simple(10); // 10
// Parametri Multipli con ()
let max = (a, b) => a > b ? a : b;
24 . 9
Altri casi
// Più semplice gestire filtering, mapping, ... di array
var arr = [5, 6, 13, 0, 1, 18, 23];
var sum = arr.reduce((a, b) => a + b); // 66
var even = arr.filter(v => v % 2 == 0); // [6, 0, 18]
var double = arr.map(v => v * 2); // [10, 12, 26, 0, 2, 36, 46]
// Le catene di promise sono più concise
promise.then(a => {
// ...
}).then(b => {
// ...
});
24 . 10
24 . 12
Altri casi
// le funzioni a freccia senza parametri sono più semplici da visualizzare
setTimeout( () => {
console.log("I happen sooner");
setTimeout( () => {
console.log("I happen later");
}, 2000);
}, 1000);
24 . 13
Parameter Handling
Il parameter handling ha ricevuto
notevoli miglioramenti in ES6.
Default parameter values
Rest parameters
Named parameters via destructuring
Spread operator
25 . 1
Default Parameters
ES6 consente di definire valori di default
per i parametri
È inoltre possibile sfruttare altre variabili o altri parametri come valori di default
25 . 2
DEFAULT PARAMETERSDEFAULT PARAMETERS
function f(x, y=0) {
return [x, y];
}
function foo(x=3, y=x) {}
foo(); // x=3; y=3
foo(7); // x=7; y=7
foo(7, 2); // x=7; y=2
const x = 'outer';
function foo(a = x) {
const x = 'inner';
console.log(a); // outer
}
25 . 3
Rest Operator
Usando il prefisso ... prima di un ultimo parametro,
permette di rappresentare un indefinito numero di
argomenti come un array
non ci sono parametri a sufficienza, l'operatore rest sarà settato come un empty Array
25 . 4
REST OPERATORREST OPERATOR
function f(x, ...y) {
console.log(x);
console.log(y);
}
f('a', 'b', 'c'); // x = 'a'; y = ['b', 'c']
25 . 5
REST OPERATORREST OPERATOR
Rest operator manda in pensione (o quasi) la variabile
speciale arguments
// ES5: arguments
function logAllArguments() {
for (var i=0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
// ES6: rest parameter
function logAllArguments(...args) {
for (const arg of args) {
console.log(arg);
}
}
25 . 6
Named Parameters
JavaScript non dispone di supporto nativo per i Named
Parameteres, ma offre una buona soluzione.
Utilizza una object literal per passare i parametri, che
sono quindi mappati.
Forniscono descrizioni per gli argomenti
nelle chiamate di funzione
Funzionano bene per i parametri opzionali
25 . 7
NAMED PARAMETERSNAMED PARAMETERS
// In ES6, puoi usare il destructuring
function selectEntries({ start=0, end=-1, step=1 } = {}) {
···
}
selectEntries({ step: 2 });
selectEntries({ end: 20, start: 3 });
selectEntries();
//In ECMAScript 5, selectEntries() si dovrebbe invece implementare come:
function selectEntries(options) {
options = options || {};
var start = options.start || 0;
var end = options.end || -1;
var step = options.step || 1;
···
}
25 . 8
REQUIRED PARAMETERSREQUIRED PARAMETERS
// ES5
function foo(mustBeProvided) {
if (arguments.length < 1) { throw new Error(); }
if (mustBeProvided === undefined) { throw new Error(); }
···
}
// ES6
// Chiamata se il parametro è assente
function mandatory() {
throw new Error('Missing parameter');
}
function foo(mustBeProvided = mandatory()) {
return mustBeProvided;
}
25 . 9
The spread operator (...)
Lo spread operator somiglia esattamente
al rest operator, ma:
Rest
operator
Raccoglie gli elementi restanti di un iterabile in un
array e viene utilizzato per rest parameters ed il
destructuring
Spread
operator
Trasforma gli elementi di un iterabile in argomenti di
una chiamata di funzione o in elementi di un array
25 . 10
SPREAD OPERATORSPREAD OPERATOR
> Math.max(-1, 5, 11, 3)
11
> Math.max(...[-1, 5, 11, 3])
11
> Math.max(-1, ...[-1, 5, 11], 3)
11
const arr1 = ['a', 'b'];
const arr2 = ['c', 'd'];
arr1.push(...arr2);
// arr1 ['a', 'b', 'c', 'd']
25 . 11
SPREAD OPERATORSPREAD OPERATOR
new Date(...[1912, 11, 24])
const x = ['a', 'b'];
const y = ['c'];
const z = ['d', 'e'];
const arr = [...x, ...y, ...z]; // ['a', 'b', 'c', 'd', 'e']
const set = new Set([11, -1, 6]);
const arr = [...set]; // [11, -1, 6]
25 . 12
Classes
Le classi introdotte in ES6 sono un'evoluzione sintattica in
confronto alla versione prototype-based.
La sintassi non introduce un nuovo modello di ereditarietà ma una sintassi molto più semplice e
pulita per creare oggetti e gestire meglio l'ereditarietà stessa
26 . 1
CLASSCLASS
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return `(${this.x}, ${this.y})`;
}
}
var p = new Point(25, 8);
p.toString()
'(25, 8)'
26 . 2
CLASSCLASS
var o = {
a: 2,
m: function(b){
return this.a + 1;
}
};
console.log(o.m()); // 3
// Chiamando o.m in questo caso, 'this' si riferisce è o.a
var p = Object.create(o);
// p è un oggetto che eredita da o
p.a = 12; // crea una propria property 'a' su p
console.log(p.m()); // 13
26 . 3
Classes
Ereditarietà Singola
Metodo Constructor
Metodi Statici
Getter e Setter
Computed method names
Ereditarietà Mixin-style
Un'importante differenza tra la dichiarazione di una funzione e la dichiarazione di una classe è
che le dichiarazioni di funzione sono hoisted, quelle per le classi no.
Bisogna dichiarare la classe e poi usarla, altrimenti verrà sollevata un'eccezione
26 . 4
Definizione Classe
//ES6
class Shape {
constructor (id, x, y) { this.id = id; this.move(x, y); }
move (x, y) { this.x = x; this.y = y }
}
//ES5
var Shape = function (id, x, y) {
this.id = id;
this.move(x, y);
};
Shape.prototype.move = function (x, y) {
this.x = x;
this.y = y;
};
26 . 5
Ereditarietà
//ES6
class Rectangle extends Shape {
constructor (id, x, y, width, height) {
super(id, x, y)
this.width = width
this.height = height
}
}
class Circle extends Shape {
constructor (id, x, y, radius) {
super(id, x, y)
this.radius = radius
}
}
26 . 6
Ereditarietà
//ES5
var Rectangle = function (id, x, y, width, height) {
Shape.call(this, id, x, y);
this.width = width;
this.height = height;
};
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;
var Circle = function (id, x, y, radius) {
Shape.call(this, id, x, y);
this.radius = radius;
};
Circle.prototype = Object.create(Shape.prototype);
Circle.prototype.constructor = Circle;
26 . 7
Super
class Cat {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Lion extends Cat {
speak() {
super.speak();
console.log(this.name + ' roars.');
}
}
26 . 8
Static Methods
//ES6
class Rectangle extends Shape {
…
static defaultRectangle () {
return new Rectangle("default", 0, 0, 100, 100)
}
}
class Circle extends Shape {
…
static defaultCircle () {
return new Circle("default", 0, 0, 100)
}
}
var defRectangle = Rectangle.defaultRectangle()
var defCircle = Circle.defaultCircle()
26 . 9
Static Methods
//ES5
var Rectangle = function (id, x, y, width, height) {
…
};
Rectangle.defaultRectangle = function () {
return new Rectangle("default", 0, 0, 100, 100);
};
var Circle = function (id, x, y, width, height) {
…
};
Circle.defaultCircle = function () {
return new Circle("default", 0, 0, 100);
};
var defRectangle = Rectangle.defaultRectangle();
var defCircle = Circle.defaultCircle();
26 . 10
Getter/Setter
//ES6
class Rectangle {
constructor (width, height) {
this._width = width
this._height = height
}
set width (width) { this._width = width }
get width () { return this._width }
set height (height) { this._height = height }
get height () { return this._height }
get area () { return this._width * this._height }
}
var r = new Rectangle(50, 20)
// r.area === 1000
26 . 11
Getter/Setter
//ES5
var Rectangle = function (width, height) {
this._width = width;
this._height = height;
};
Rectangle.prototype = {
set width (width) { this._width = width; },
get width () { return this._width; },
set height (height) { this._height = height; },
get height () { return this._height; },
get area () { return this._width * this._height; }
};
var r = new Rectangle(50, 20);
// r.area === 1000;
26 . 12
Class Expression
// unnamed
var Polygon = class {
constructor(height, width) {
this.height = height;
this.width = width;
}
};
// named
var Polygon = class Polygon {
constructor(height, width) {
this.height = height;
this.width = width;
}
};
26 . 13
Ereditarietà Mixin-style
class Person { ··· }
class Employee extends Person { ··· }
class Storage {
save(database) { ··· }
}
class Validation {
validate(schema) { ··· }
}
// Sarebbe bella una ES6 syntax:
class Employee extends Storage, Validation, Person { ··· }
26 . 14
Ereditarietà Mixin-style
const Storage = Sup => class extends Sup {
save(database) { ··· }
};
const Validation = Sup => class extends Sup {
validate(schema) { ··· }
};
class Employee extends Storage(Validation(Person)) { ··· }
26 . 15
Modules
ES6 ha aggiunto finalmente il supporto nativo ai moduli,
evitando il ricorso a soluzioni ad hoc e alla
implementazione del Module Pattern
Secondo le specifiche, un modulo JavaScript è memorizzato in un file:
esiste esattamente un modulo per file e un file contiene un solo modulo.
27 . 1
MODULE PATTERNMODULE PATTERN
var modulo = (function() {
function metodoPrivato() {
//...
}
return {
metodoPubblico: function() {
metodoPrivato();
}
}
})();
27 . 2
MODULE PATTERNMODULE PATTERN
// Import Moduli Esterni
var altroModulo = (function() {
//...
})();
var modulo = (function(moduloEsterno) {
function metodoPrivato() {
moduloEsterno.metodo();
//...
}
return {
metodoPubblico: function() {
metodoPrivato();
}
}
})(altroModulo);
27 . 3
Export
//------ 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));
}
// È anche possibile esportare più elementi
const sqrt = Math.sqrt;
function square(x) {
return x * x;
}
function diag(x, y) {
return sqrt(square(x) + square(y));
}
export {sqrt, square, diag};
27 . 4
Import
//------ main.js ------
import { square, diag } from 'lib';
console.log(square(11)); //121
console.log(diag(4,3)); //5
// È possibile usare degli alias
//------ main.js ------
import { square, diag as diagonal } from 'lib';
console.log(square(11)); // 121
console.log(diagonal(4, 3)); // 5
// Per importare l'intero modulo:
//------ main.js ------
import * as lib from 'lib';
console.log(lib.square(11)); // 121
console.log(lib.diag(4, 3)); // 5
27 . 5
Default Export
//------ myFunc.js ------
export default function () { ··· } // no semicolon!
//------ main1.js ------
import myFunc from 'myFunc';
myFunc();
//------ MyClass.js ------
export default class { ··· } // no semicolon!
//------ main2.js ------
import MyClass from 'MyClass';
const inst = new MyClass();
27 . 6
Alcune Note
L’importazione e l’esportazione di un modulo
sono processi statici
Non è possibile importare ed esportare un modulo a runtime in base alla valutazione di determinate condizioni
L’importazione di un modulo è soggetta ad hoisting
Gli elementi importati da un modulo sono in sola lettura
Questa funzionalità non ha ancora un supporto nativo crossbrowser, ma viene implementato in molti traspilers o
module bundlers come: Traceur Compiler, Babel, Rollup e Webpack.
27 . 7
Alcune Note
Ogni modulo viene eseguito una volta completamente caricato.
Nei moduli sono presenti dichiarazioni (dichiarazioni variabili,
dichiarazioni di funzione, ecc.).
Per impostazione predefinita, queste dichiarazioni rimangono locali nel modulo
È possibile contrassegnare alcune di esse come export, così che altri moduli possono importarli
27 . 8
Alcune Note
Un modulo può importare elementi da altri moduli, riferendosi
agli altri moduli con stringhe:
Relative paths ('../model/user')
Absolute paths ('/lib/js/helpers')
I Moduli sono singleton.
Questo approccio evita le variabili globali,
l'unica cosa globale sono i moduli stessi.
27 . 9
Array
Array.from Converte un array-like object in array
Array.of Un nuovo modo di creare array
Array.prototype.entries Ritorna un Array Iterator con
chiave/valore
Array.prototype.keys Ritorna un Array Iterator con chiave
Array.prototype.values Ritorna un Array Iterator con valore
28 . 1
Array
Array.prototype.find Ritorna il valore del primo elemento
che soddisfa i requisiti
Array.prototype.findIndex Ritorna l'indice del primo elemento
che soddisfa i requisiti
Array.prototype.fill Popola con un valore statico gli
elementi di un array da un indice di
partenza ad uno di fine
28 . 2
Maps/Sets (Collections)
Strutture dati molto comode per gestire insiemi,
così da evitare artifici per fare operazioni abbastanza
comuni.
Sets Un Set può contenere dati di qualsiasi tipo ma senza
duplicati.
Maps Il Map object è una semplice coppia chiave/valore.
Qualunque objects o primitive può essere usato sia come
chiave che valore.
29 . 1
Maps
var myMap = new Map();
var keyString = "a string",
keyObj = {},
keyFunc = function () {};
// Setting dei valori
myMap.set(keyString, "value associated with 'a string'");
myMap.set(keyObj, "value associated with keyObj");
myMap.set(keyFunc, "value associated with keyFunc");
myMap.size; // 3
29 . 2
Maps
// Getting dei valori
myMap.get(keyString); // "value associated with 'a string'"
myMap.get(keyObj); // "value associated with keyObj"
myMap.get(keyFunc); // "value associated with keyFunc"
myMap.get("a string"); // "value associated with 'a string'"
// perchè keyString === 'a string'
myMap.get({}); // undefined, perchè keyObj !== {}
myMap.get(function() {}) // undefined, perchè keyFunc !== function () {}
29 . 3
Sets
var mySet = new Set();
mySet.add(1); // Set { 1 }
mySet.add(5); // Set { 1, 5 }
mySet.add(5); // Set { 1, 5 }
mySet.add('some text'); // Set { 1, 5, 'some text' }
var o = {a: 1, b: 2};
mySet.add(o);
// o si riferisce ad un differente oggetto, quindi è consentito
mySet.add({a: 1, b: 2});
29 . 4
Sets
mySet.has(1); // true
mySet.has(3); // false, 3 non è stato aggiunto al Set
mySet.has(5); // true
mySet.has(Math.sqrt(25)); // true
mySet.has('Some Text'.toLowerCase()); // true
mySet.has(o); // true
mySet.size; // 5
mySet.delete(5); // Rimuove 5 dal set
mySet.has(5); // false, 5 è stato rimosso
mySet.size; // 4, abbiamo appena rimosso un valore
console.log(mySet);
// Set {1, "some text", Object {a: 1, b: 2}, Object {a: 1, b: 2}}
29 . 5
Symbol
Symbol è una nuova primitiva di ES6
Ogni qualvolta chiamamo la factory function, un nuovo symbol
univoco verrà creato.
let x = Symbol("mioSimbolo");
Symbols come chiave è una of non-public properties
(non sarà restituita da JSON.stringify o getOwnPropertyNames)
Un object sarà iterabile se esso avrà un metodo la quale chiave è
Symbol.iterator
30 . 1
Symbol
const symbol1 = Symbol();
> Symbol() === Symbol()
false
//Symbols può essere usato come chiave di una proprietà:
const MY_KEY = Symbol();
const FOO = Symbol();
const obj = {};
30 . 2
Symbol
obj[MY_KEY] = 123; //computed property keys
console.log(obj[MY_KEY]); // 123
const obj = {
data: [ 'hello', 'world' ],
[Symbol.iterator]() { ··· }
};
for (const x of obj) {
console.log(x);
}
// Output:
// hello
// world
30 . 3
Alcuni usi
Identificare un oggetto in maniera univoca assegnando un valore
alla sua proprietà id
Definizione di enumerazioni
(comunemente definiti con interi)
Definire una proprietà non visibile nell’elenco delle proprietà
dell’oggetto
Rendere iterabile una collezione di valori
(con l'uso di Symbol.iterator)
30 . 4
Iterators e Generators
L'elaborazione di ciascuno degli elementi di una
collezione è un'operazione molto comune.
JavaScript offre diversi modi di iterazione su una
raccolta, da semplici for loops a map() e filter().
Iterators e Generators portano il concetto di iterazione
direttamente nel core del linguaggio e forniscono un
meccanismo per personalizzare, ad esempio, il
comportamento di for...of.
31 . 1
Iterators
Un oggetto è definito Iterator se ha l'abilità di accedere gli
elementi di una collezione, uno alla volta e tenere traccia della
propria posizione nell'iterazione.
Un iteratore possiede il metodo next(), che ritorna il prossimo
elemento dell'iterazione.
Questo elemento ritornato, è un oggetto con due proprietà: done
e value.
String, Array, TypedArray, Map, Set, ... sono tutti iterabili predefiniti.
31 . 2
Generators
I generatori permettono di scrivere una funzione generatore
function* nome([param[, param[, ... param]]]) { }
che tiene traccia della propria posizione ed ha il metodo next().
I generatori ritornano un oggetto Generator.
La parola chiave yield viene usata per mettere in pausa e
riprendere l'esecuzione di una funzione generatore.
31 . 3
Iterators
function makeIterator(array) {
var nextIndex = 0;
return {
next: function() {
return nextIndex < array.length ?
{value: array[nextIndex++], done: false} :
{done: true};
}
};
}
var it = makeIterator(['yo', 'ya']);
console.log(it.next().value); // 'yo'
console.log(it.next().value); // 'ya'
console.log(it.next().done); // true
31 . 4
Iterators (TS)
interface Iterable {
[Symbol.iterator]() : Iterator;
}
interface Iterator {
next() : IteratorResult;
return?(value? : any) : IteratorResult;
}
interface IteratorResult {
value: any;
done: boolean;
}
31 . 5
Iterators
function iterateOver(...args) {
let index = 0;
const iterable = {
[Symbol.iterator]() {
const iterator = {
next() {
if (index < args.length) {
return { value: args[index++] };
} else {
return { done: true };
}
}
};
return iterator;
}
}
t it bl
31 . 6
Iterators
// Usando `iterateOver()`:
for (const x of iterateOver('fee', 'fi', 'fo', 'fum')) {
console.log(x);
}
// Output: fee, fi, fo, fum
31 . 7
Generators
function* idMaker() {
var index = 0;
while(true)
yield index++;
}
var gen = idMaker();
console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
31 . 8
Generators
function* objectEntries(obj) {
const propKeys = Reflect.ownKeys(obj);
for (const propKey of propKeys) {
// `yield` ritorna un valore e mette in pausa il generator.
// Dopo l'esecuzione riprendere da dove era stata messa in pausa
yield [propKey, obj[propKey]];
}
}
const jane = { first: 'Jane', last: 'Doe' };
for (const [key,value] of objectEntries(jane)) {
console.log(`${key}: ${value}`);
}
// Output:
// first: Jane
// last: Doe
31 . 9
Objects Iterabili
var oggIterabile = {};
oggIterabile[Symbol.iterator] = function* () {
yield 1;
yield 2;
yield 3;
};
for (let valore of oggIterabile) {
console.log(valore);
}
31 . 10
Async JS
Le operazioni asincrone sono sempre più comuni e
fortunatamente sempre più comode da gestire
È finito l'inferno delle callback...
benvenuti Promise ed Async/Await
Promise ed Async/Await consentono la gestione di
operazioni asincrone con semplicità ed enorme potenza
espressiva.
32 . 1
Promise
new Promise(function(resolve, reject) { ... });
Gli oggetti Promise sono usati per computazioni
in differita e asincrone.
Una Promise rappresenta un'operazione che non è ancora
completata, ma lo sarà in futuro.
Una Promise rappresenta un proxy per un valore non necessariamente noto quando la promise è stata creata.
32 . 2
Promise
Una Promise può presentarsi in uno dei seguenti stati:
pending (attesa) - stato iniziale, né soddisfatto né respinto.
fulfilled (soddisfatto) - significa che l'operazione si è conclusa con
sucesso.
rejected (respinto) - significa che l'operazione à fallita.
32 . 3
Promise
let myFirstPromise = new Promise((resolve, reject) => {
// Chiamiamo resolve(...) quando viene eseguito correttamente, e reject(...
// In questo esempio viene utilizzato setTimeout(...) per simulare un'opera
// Nella realtà probabilmente utilizzerai qualcosa del tipo XHR o HTML5 API
setTimeout(function(){
resolve("Success!"); // È andato tutto perfettamente!
}, 250);
});
myFirstPromise.then((successMessage) => {
// successMessage viene passato alla funzione resolve(...) .
// Non deve essere necessariamente una stringa, ma nel caso sia solo un mes
console.log("Yay! " + successMessage);
});
32 . 4
Promise
fs.readFile('config.json',
function (error, text) {
if (error) {
console.error('Error while reading config file');
} else {
try {
const obj = JSON.parse(text);
console.log(JSON.stringify(obj, null, 4));
} catch (e) {
console.error('Invalid JSON in file');
}
}
});
32 . 5
Promise
readFilePromisified('config.json')
.then(function (text) { // (A)
const obj = JSON.parse(text);
console.log(JSON.stringify(obj, null, 4));
})
.catch(function (error) { // (B)
// File read error or JSON SyntaxError
console.error('An error occurred', error);
});
32 . 6
Promise
function httpGet(url) {
return new Promise(
function (resolve, reject) {
const request = new XMLHttpRequest();
request.onload = function () {
if (this.status === 200) {
// Success
resolve(this.response);
} else {
// Something went wrong (404 etc.)
reject(new Error(this.statusText));
}
};
request.onerror = function () {
reject(new Error(
'XMLHttpRequest Error: '+this.statusText));
}
32 . 7
Promise
httpGet('http://example.com/file.txt')
.then(
function (value) {
console.log('Contents: ' + value);
},
function (reason) {
console.error('Something went wrong', reason);
});
32 . 8
Promise
I metodi che fanno la differenza
Promise.all
Promise.race
Promise.resolve
Promise.reject
32 . 9
Async/Await
Una delle più attese novità introdotte da ECMAScript 2017 è stato
il supporto di async/await.
Si tratta di due parole chiave che abilitano la gestione di funzioni
asincrone eseguite tramite un approccio sincrono.
Consente la scrittura di codice asincrono pur mantenendo una struttura di codice tipico della programmazione
sincrona
Si basano sul meccanismo delle Promise e il loro risultato è compatibile con qualsiasi API che utilizza le Promise.
32 . 10
Async/Await
Async
La parola async prima di una funzione significa una
cosa semplice: una funzione restituisce sempre una
Promise.
32 . 11
Async/Await
async function f() {
return 1;
}
f().then(alert); // 1
async function f() {
return Promise.resolve(1);
}
f().then(alert); // 1
32 . 12
Async/Await
async function f() {
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("done!"), 1000)
});
let result = await promise; // wait till the promise resolves (*)
alert(result); // "done!"
}
f();
32 . 13
Async/Await
function getUtente(userId) {
fetch("/utente/" + userId).then(response => {
console.log(response);
}).catch(error => console.log("Si è verificato un errore!"));
}
async function getUtente(userId) {
try {
let response = await fetch("/utente/" + userId);
console.log(response);
} catch (e) {
console.log("Si è verificato un errore!");
}
}
32 . 14
Async/Await
async function getBlogAndPhoto(userId) {
try {
let utente = await fetch("/utente/" + userId);
let blog = await fetch("/blog/" + utente.blogId);
let foto = await fetch("/photo/" + utente.albumId);
return {
utente,
blog,
foto
};
} catch (e) {
console.log("Si è verificato un errore!");
}
}
32 . 15
Async/Await
Vediamo insieme l'evoluzione
32 . 16
Ancora su ES6, ES7...ESx
Ci vorrebbe un'eternità!
Promise & Async/Await
RegEx
Trailing commas (function parameter)
Asynchronous iteration
Array/Object/String Updates
Rest/Spread Updates
BigInt
Dynamic Import
33
Qualche link utile
https://github.com/lukehoban/es6features
https://github.com/ryanmcdermott/clean-code-
javascript#classes
https://github.com/airbnb/javascript>
http://es6-features.org/
34
Grazie a tutti!
35

Mais conteúdo relacionado

Mais procurados

Le funzioni in javascript
Le funzioni in javascriptLe funzioni in javascript
Le funzioni in javascriptPaoloCaramanica
 
Programmazione Funzionale per tutti
Programmazione Funzionale per tuttiProgrammazione Funzionale per tutti
Programmazione Funzionale per tuttiSalvatore Sorrentino
 
JavaScript Object Oriented
JavaScript Object OrientedJavaScript Object Oriented
JavaScript Object OrientedManuel Scapolan
 
14 - Programmazione: Stream e File
14 - Programmazione: Stream e File14 - Programmazione: Stream e File
14 - Programmazione: Stream e FileMajong DevJfu
 
Introduzione a JavaScript
Introduzione a JavaScriptIntroduzione a JavaScript
Introduzione a JavaScriptGiovanni Buffa
 
What is new in C# 2018
What is new in C# 2018What is new in C# 2018
What is new in C# 2018Marco Parenzan
 
Cattive abitudini e-lineeguida
Cattive abitudini e-lineeguidaCattive abitudini e-lineeguida
Cattive abitudini e-lineeguidaRobert Casanova
 
Corso Programmazione Java Base
Corso Programmazione Java BaseCorso Programmazione Java Base
Corso Programmazione Java BaseK-Tech Formazione
 
Pycrashcourse3.1
Pycrashcourse3.1Pycrashcourse3.1
Pycrashcourse3.1rik0
 
LINQ, Entities Framework & ORMs
LINQ, Entities Framework & ORMsLINQ, Entities Framework & ORMs
LINQ, Entities Framework & ORMsJUG Genova
 
Lezione 12 (28 marzo 2012)
Lezione 12 (28 marzo 2012)Lezione 12 (28 marzo 2012)
Lezione 12 (28 marzo 2012)STELITANO
 
Laboratorio Programmazione: In - Out variabili
Laboratorio Programmazione: In - Out variabiliLaboratorio Programmazione: In - Out variabili
Laboratorio Programmazione: In - Out variabiliMajong DevJfu
 
PHP: strutture di controllo e funzioni
PHP: strutture di controllo e funzioniPHP: strutture di controllo e funzioni
PHP: strutture di controllo e funzioniextrategy
 
Pycrashcourse3.0
Pycrashcourse3.0Pycrashcourse3.0
Pycrashcourse3.0rik0
 

Mais procurados (20)

Le funzioni in javascript
Le funzioni in javascriptLe funzioni in javascript
Le funzioni in javascript
 
DHow2 - L1
DHow2 - L1DHow2 - L1
DHow2 - L1
 
Programmazione Funzionale per tutti
Programmazione Funzionale per tuttiProgrammazione Funzionale per tutti
Programmazione Funzionale per tutti
 
JavaScript Object Oriented
JavaScript Object OrientedJavaScript Object Oriented
JavaScript Object Oriented
 
14 - Programmazione: Stream e File
14 - Programmazione: Stream e File14 - Programmazione: Stream e File
14 - Programmazione: Stream e File
 
Introduzione a JavaScript
Introduzione a JavaScriptIntroduzione a JavaScript
Introduzione a JavaScript
 
What is new in C# 2018
What is new in C# 2018What is new in C# 2018
What is new in C# 2018
 
Cattive abitudini e-lineeguida
Cattive abitudini e-lineeguidaCattive abitudini e-lineeguida
Cattive abitudini e-lineeguida
 
Corso Programmazione Java Base
Corso Programmazione Java BaseCorso Programmazione Java Base
Corso Programmazione Java Base
 
Pycrashcourse3.1
Pycrashcourse3.1Pycrashcourse3.1
Pycrashcourse3.1
 
LINQ, Entities Framework & ORMs
LINQ, Entities Framework & ORMsLINQ, Entities Framework & ORMs
LINQ, Entities Framework & ORMs
 
2008 python
2008 python2008 python
2008 python
 
2006 Py02 base
2006 Py02 base2006 Py02 base
2006 Py02 base
 
Lezione 12 (28 marzo 2012)
Lezione 12 (28 marzo 2012)Lezione 12 (28 marzo 2012)
Lezione 12 (28 marzo 2012)
 
Laboratorio Programmazione: In - Out variabili
Laboratorio Programmazione: In - Out variabiliLaboratorio Programmazione: In - Out variabili
Laboratorio Programmazione: In - Out variabili
 
PHP: strutture di controllo e funzioni
PHP: strutture di controllo e funzioniPHP: strutture di controllo e funzioni
PHP: strutture di controllo e funzioni
 
Js intro
Js introJs intro
Js intro
 
2006 Py03 intermedio
2006 Py03 intermedio2006 Py03 intermedio
2006 Py03 intermedio
 
05 1 intro-struttura
05 1 intro-struttura05 1 intro-struttura
05 1 intro-struttura
 
Pycrashcourse3.0
Pycrashcourse3.0Pycrashcourse3.0
Pycrashcourse3.0
 

Semelhante a Acadevmy - ES6 Modern JS Today

.Net 4.0 Preview @ UGIdotNet
.Net 4.0 Preview @ UGIdotNet.Net 4.0 Preview @ UGIdotNet
.Net 4.0 Preview @ UGIdotNetMauro Servienti
 
Primo Incontro Con Scala
Primo Incontro Con ScalaPrimo Incontro Con Scala
Primo Incontro Con ScalaFranco Lombardo
 
Reactive programming principles
Reactive programming principlesReactive programming principles
Reactive programming principlesRiccardo Cardin
 
corso web developer - Introduzione a Javascript
corso web developer - Introduzione a Javascriptcorso web developer - Introduzione a Javascript
corso web developer - Introduzione a JavascriptRiccardo Piccioni
 
Deep diving C# 4 (Raffaele Rialdi)
Deep diving C# 4 (Raffaele Rialdi)Deep diving C# 4 (Raffaele Rialdi)
Deep diving C# 4 (Raffaele Rialdi)DotNetMarche
 
EF 6.0 What's New - EF@Work
EF 6.0 What's New - EF@WorkEF 6.0 What's New - EF@Work
EF 6.0 What's New - EF@WorkPietro Libro
 
Reactive programming con RxJS
Reactive programming con RxJSReactive programming con RxJS
Reactive programming con RxJSNucleode Srl
 
How create a single page apps using html5 and javascript
How create a single page apps using html5 and javascript How create a single page apps using html5 and javascript
How create a single page apps using html5 and javascript Stefano Marchisio
 
Mobile APPs con Objective-C (iOS 3.1+) - Day 01/02
Mobile APPs con Objective-C (iOS 3.1+) - Day 01/02Mobile APPs con Objective-C (iOS 3.1+) - Day 01/02
Mobile APPs con Objective-C (iOS 3.1+) - Day 01/02Alberto Pasca
 
Dominare il codice legacy
Dominare il codice legacyDominare il codice legacy
Dominare il codice legacyTommaso Torti
 

Semelhante a Acadevmy - ES6 Modern JS Today (20)

Camera Parser
Camera ParserCamera Parser
Camera Parser
 
.Net 4.0 Preview @ UGIdotNet
.Net 4.0 Preview @ UGIdotNet.Net 4.0 Preview @ UGIdotNet
.Net 4.0 Preview @ UGIdotNet
 
Primo Incontro Con Scala
Primo Incontro Con ScalaPrimo Incontro Con Scala
Primo Incontro Con Scala
 
Reactive programming principles
Reactive programming principlesReactive programming principles
Reactive programming principles
 
Java codestyle & tipstricks
Java codestyle & tipstricksJava codestyle & tipstricks
Java codestyle & tipstricks
 
Corso java base
Corso java baseCorso java base
Corso java base
 
Hexagonal architecture ita
Hexagonal architecture itaHexagonal architecture ita
Hexagonal architecture ita
 
corso web developer - Introduzione a Javascript
corso web developer - Introduzione a Javascriptcorso web developer - Introduzione a Javascript
corso web developer - Introduzione a Javascript
 
Html5 e PHP
Html5 e PHPHtml5 e PHP
Html5 e PHP
 
Deep diving C# 4 (Raffaele Rialdi)
Deep diving C# 4 (Raffaele Rialdi)Deep diving C# 4 (Raffaele Rialdi)
Deep diving C# 4 (Raffaele Rialdi)
 
EF 6.0 What's New - EF@Work
EF 6.0 What's New - EF@WorkEF 6.0 What's New - EF@Work
EF 6.0 What's New - EF@Work
 
Vb.Net
Vb.NetVb.Net
Vb.Net
 
Reactive programming con RxJS
Reactive programming con RxJSReactive programming con RxJS
Reactive programming con RxJS
 
Javascript
JavascriptJavascript
Javascript
 
How create a single page apps using html5 and javascript
How create a single page apps using html5 and javascript How create a single page apps using html5 and javascript
How create a single page apps using html5 and javascript
 
Mobile APPs con Objective-C (iOS 3.1+) - Day 01/02
Mobile APPs con Objective-C (iOS 3.1+) - Day 01/02Mobile APPs con Objective-C (iOS 3.1+) - Day 01/02
Mobile APPs con Objective-C (iOS 3.1+) - Day 01/02
 
Yagwto
YagwtoYagwto
Yagwto
 
Java lezione 14
Java lezione 14Java lezione 14
Java lezione 14
 
Dominare il codice legacy
Dominare il codice legacyDominare il codice legacy
Dominare il codice legacy
 
Riepilogo Java C/C++
Riepilogo Java C/C++Riepilogo Java C/C++
Riepilogo Java C/C++
 

Mais de Francesco Sciuti

Siamo tutti bravi con il browser degli altri!
Siamo tutti bravi con il browser degli altri!Siamo tutti bravi con il browser degli altri!
Siamo tutti bravi con il browser degli altri!Francesco Sciuti
 
Deno - L'anagramma di node
Deno - L'anagramma di nodeDeno - L'anagramma di node
Deno - L'anagramma di nodeFrancesco Sciuti
 
Acadevmy - Visual Studio Code Overview
Acadevmy - Visual Studio Code OverviewAcadevmy - Visual Studio Code Overview
Acadevmy - Visual Studio Code OverviewFrancesco Sciuti
 
Acadevmy - AngularDay 2018 - Change Detection, Zone.js ed altri mostri
Acadevmy - AngularDay 2018 - Change Detection, Zone.js ed altri mostriAcadevmy - AngularDay 2018 - Change Detection, Zone.js ed altri mostri
Acadevmy - AngularDay 2018 - Change Detection, Zone.js ed altri mostriFrancesco Sciuti
 
Acadevmy - Angular Overview
Acadevmy - Angular OverviewAcadevmy - Angular Overview
Acadevmy - Angular OverviewFrancesco Sciuti
 
Acadevmy - Google Conversation design
Acadevmy - Google Conversation designAcadevmy - Google Conversation design
Acadevmy - Google Conversation designFrancesco Sciuti
 
Acadevmy - GraphQL & Angular: Tutto il REST è noia!
Acadevmy - GraphQL & Angular: Tutto il REST è noia!Acadevmy - GraphQL & Angular: Tutto il REST è noia!
Acadevmy - GraphQL & Angular: Tutto il REST è noia!Francesco Sciuti
 

Mais de Francesco Sciuti (11)

Siamo tutti bravi con il browser degli altri!
Siamo tutti bravi con il browser degli altri!Siamo tutti bravi con il browser degli altri!
Siamo tutti bravi con il browser degli altri!
 
Microsoft Fast - Overview
Microsoft Fast - OverviewMicrosoft Fast - Overview
Microsoft Fast - Overview
 
Creare PWA con Angular
Creare PWA con AngularCreare PWA con Angular
Creare PWA con Angular
 
Deno - L'anagramma di node
Deno - L'anagramma di nodeDeno - L'anagramma di node
Deno - L'anagramma di node
 
Acadevmy - PWA Overview
Acadevmy - PWA OverviewAcadevmy - PWA Overview
Acadevmy - PWA Overview
 
Acadevmy - Visual Studio Code Overview
Acadevmy - Visual Studio Code OverviewAcadevmy - Visual Studio Code Overview
Acadevmy - Visual Studio Code Overview
 
Acadevmy - AngularDay 2018 - Change Detection, Zone.js ed altri mostri
Acadevmy - AngularDay 2018 - Change Detection, Zone.js ed altri mostriAcadevmy - AngularDay 2018 - Change Detection, Zone.js ed altri mostri
Acadevmy - AngularDay 2018 - Change Detection, Zone.js ed altri mostri
 
Acadevmy - Angular Overview
Acadevmy - Angular OverviewAcadevmy - Angular Overview
Acadevmy - Angular Overview
 
Acadevmy - Google Conversation design
Acadevmy - Google Conversation designAcadevmy - Google Conversation design
Acadevmy - Google Conversation design
 
Acadevmy - PWA & Angular
Acadevmy - PWA & AngularAcadevmy - PWA & Angular
Acadevmy - PWA & Angular
 
Acadevmy - GraphQL & Angular: Tutto il REST è noia!
Acadevmy - GraphQL & Angular: Tutto il REST è noia!Acadevmy - GraphQL & Angular: Tutto il REST è noia!
Acadevmy - GraphQL & Angular: Tutto il REST è noia!
 

Acadevmy - ES6 Modern JS Today

  • 1. 1
  • 2. Software Factory Web Mobile DevOps Labs Formazione 2
  • 3. Volete collaborare con noi? Avete questo coraggio? :D info@acadevmy.it 3
  • 5. 5
  • 6. Chi Sono? Developer per scelta e per passione, amante di nerdaggini di ogni tipo ed amante della condivisione del sapere! 6 . 1
  • 7. Compilate il modulo di Feedback e dateci il vostro giudizio! Abbiamo deciso di risparmiare carta a favore dell'ambiente! 7
  • 8. ed ora è il momento di Built with ❤ for the Web Cos'è? Come funziona? Perché è figo? 8
  • 9. Ma facciamo un passo indietro... 9
  • 10. CrossDevice Web Browser Desktop Mobile: phone e tablet TV / LFD / Walls Wearable Totem / Kiosk IoT Isomorfo CrossPlatform Windows OS X Linux Android iOS Windows Phone Chromium WEB / HYBRID applications Javascript 10
  • 11. Terminologia JavaScript Il nome del linguaggio o meglio un'implementazione dello standard ECMAScript Lo standard del linguaggio TC 39 La commissione tecnica (nel passato abbastanza turbolenta!) ECMAScript Harmony Il nome in codice migliorie post ES5 un modo per dirsi...volemose bene! ECMAScript.Next Il nome in codice per le release successive ECMAScript20XX/ESX Le release rilasciate 11
  • 12. Breve Storia di JS 1995 Mocha 1996 Standardizzazione ECMA 1997 ECMA-262 (ES1) 1998 ES2 1999 ES3 2008 ES4 (abbandonato) 2009 ES5 (prima 3.1) 2015 ECMASCRIPT2015/ES6 201x ECMASCRIPT201x/ESx+1 12
  • 13. Tappe Fondamentali '90 DHTML, Forms Validation, Optimization for Browser, etc... 2000 2004 Browser Wars, Implementazioni ECMAScript (Jscript, ActionScript, etc...) 2005 Ajax, jQuery, Mootols, Prototype, etc... 2009 NodeJs 2010 2015 Frameworks, Packet Manager, Modules Manager, Preprocessor, Transpiler, etc... 13
  • 15. Corregge alcuni dei problemi più comuni di ES5 Compatibilità verso il passato (pensiamolo come un superset di ES5) Sintassi Moderna (evitiamo battute!) Pronto per le applicazioni complesse e scalabili Tante nuove funzionalità nella libreria standard 15
  • 16. Figo...quindi posso usare tranquillamente ES6? La risposta è no! :D 16
  • 17. ES6 aggiorna la lingua senza breacking changes. L'approccio adottato è chiamato One JavaScript Il cui principio è: “don’t break the web”. Molte delle funzionalità di ES6 è già supportata negli engine attuali, ma non tutte e quindi... ...per usare ES6 è richiesto l'uso di transpiler/compiler: Babel, Traceur, Typescript compiler, ... Tabella di compatibilità 17
  • 19. Modules Classes Decorators (ES7) Promises Interators e generators Multi-line Strings Destructuring Assignment Arrow Functions Default Parameters Enhancements in Object and Array Block-Scoped Constructs let e const Caratteristiche 19
  • 20. Costanti e Variabili ES6 fornisce due modi nuovi per dichiarare variabili: let e const, che sostituiscono prevalentemente il modo ES5 di dichiarare variabili, var. 20 . 1
  • 21. Scope Lo scope è il contesto corrente del codice, e gli ambiti possono essere definiti globalmente o localmente. 20 . 2
  • 22. Scope Prima di scrivere una linea di JavaScript siamo nel Global Scope Ogni funzione definita in un'altra funzione ha un ambito locale collegato alla funzione esterna Nuove funzioni = Nuovo scope Lexical scope. Ogni variables/objects/functions definite nel parent scope, sono disponibili nello scope chain ma non viceversa Quando si risolve una variabile, JavaScript inizia dallo scope più interno verso l'esterno finché non la trova 20 . 3
  • 23. Hoisting L'Hoisting è un meccanismo JavaScript per cui le variabili e le dichiarazioni di funzione vengono spostate in cima al loro ambito prima dell'esecuzione del codice. 20 . 4
  • 24. HOISTINGHOISTING function foo() { bar(); var x = 1; } function foo() { var x; bar(); x = 1; } 20 . 5
  • 25. HOISTINGHOISTING function test() { foo(); // TypeError "foo is not a function" bar(); // "questa va bene!" var foo = function () { // function expression to local var 'foo' alert("non va bene!"); } function bar() { // function declaration 'bar' alert("questa va bene!"); } } test(); 20 . 6
  • 26. let / const let La variabile che dichiara è block-scoped, quindi esiste solo all'interno del blocco corrente. var è function-scoped. const Funziona come let, ma la variabile da dichiarare deve essere immediatamente inizializzata, con un valore che non può essere modificato 20 . 7
  • 27. Costanti e Variabili   Hoisting Scope Creates global properties var Declaration Function Yes let Temporal dead zone Block No const Temporal dead zone Block No function Complete Block Yes class No Block No import Complete Module- global No 20 . 8
  • 28. Let let permette di dichiarare variabili limitandone la visibilità ad un blocco di codice, ad un assegnazione, ad un espressione in cui è usata. La parola chiave var invece definisce una variabile globalmente in uno script o localmente in un qualunque blocco di codice di una funzione. 20 . 9
  • 29. LETLET var a = 5; var b = 10; if (a === 5) { let a = 4; // Lo scope è block-level var b = 1; // Lo scope è function-level console.log(a); // 4 console.log(b); // 1 } console.log(a); // 5 console.log(b); // 1 20 . 10
  • 30. LETLET for (let i = 0; i<10; i++) { alert(i); // 1, 2, 3, 4 ... 9 } alert(i); // i non è definita 20 . 11
  • 31. Const Le costanti (create quindi con const) sono immutabili. non è possibile assegnare loro valori diversi La dichiarazione const crea un riferimento di sola lettura a un valore. Non significa che il valore che detiene è immutabile, solo che l'identificatore della variabile non può essere riassegnato. Le variabili dichiarate con const vanno inizializzate 20 . 12
  • 32. CONSTCONST //Le costanti possono essere dichiarate sia in maiuscolo che in minuscolo, //ma la convezione suggerisce il maiuscolo. const MY_FAV = 7; // Definisco la costante ed assegno il valore MY_FAV = 20; // questa istruzione provocherà un errore // questa istruzione stamperà il valore 7 console.log('my favorite number is: ' + MY_FAV); const MY_FAV = 20; //provare a ridichiarare una costante provoca un errore // e non può essere riutilizzata in altri tipi di dichiarazione var MY_FAV = 20; let MY_FAV = 20; 20 . 13
  • 33. CONSTCONST const FOO; // Errore manca l'inizializzatore // const lavora anche con gli objects const MY_OBJECT = {'key': 'value'}; MY_OBJECT = {'OTHER_KEY': 'value'}; //errore // Tuttavia, le chiavi oggetto non sono protette // e quindi viene eseguita la seguente istruzione senza problemi // Usa Object.freeze() per rendere l'oggetto immutabile MY_OBJECT.key = 'otherValue'; // const lavora anche con gli array const MY_ARRAY = []; // è possibile aggiungere elementi all'array MY_ARRAY.push('A'); // ["A"] // ma assegnare un nuovo array provocherebbe errore MY_ARRAY = ['B'] 20 . 14
  • 34. BLOCK-SCOPINGBLOCK-SCOPING // È importante notare la natura del block-scoping if (MY_FAV === 7) { // questo va bene e crea una variabile MY_FAV a livello di blocco let MY_FAV = 20; // MY_FAV è adesso 20 console.log('my favorite number is ' + MY_FAV); // ma questa operazione sposta nel global-context (via hoisting) //e provocherà errore var MY_FAV = 20; } // MY_FAV è ancora 7 console.log('my favorite number is ' + MY_FAV); 20 . 15
  • 35. Temporal Dead Zone Il tempo tra l'inizio del blocco e la dichiarazione è chiamata TDZ. Una variabile dichiarata da let o const ha una cosiddetta zona morta temporale (TDZ): Quando si entra nel campo di applicazione, non è possibile accedere (get o set) finché l'esecuzione non raggiunge la dichiarazione. let e const non sono soggetti al Variable Hoisting, difatti riferendo la variabile nel blocco prima dell'inizializzazione si ottiene un ReferenceError. 20 . 16
  • 36. TDZTDZ let tmp = true; if (true) { // entra in un nuovo scope, TDZ inizia // Viene creato un binding non ancora inizializzato per `tmp` console.log(tmp); // ReferenceError let tmp; // TDZ si conclude, `tmp`è inizializzato con `undefined` console.log(tmp); // undefined tmp = 123; console.log(tmp); // 123 } console.log(tmp); // true // La TDZ finisce dopo che l'inizializzazione // è stata valutata ed assegnata alla variabile let foo = console.log(foo); // ReferenceError 20 . 17
  • 37. Let / Const in loop heads In For Loop var binda singolarmente il valore, mentre let redichiara la variabile. In For-of e For-in, var binda singolarmente il valore, mentre let e const redichiara la variabile. 20 . 18
  • 38. FORFOR const 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()); // [0,1,2] // TypeError: assegnazione ad una costante (a causa di i++) for (const i=0; i<3; i++) { console.log(i); } 20 . 19
  • 39. FOR-OF / FOR-INFOR-OF / FOR-IN const arr = []; for (var i of [0, 1, 2]) { arr.push(() => i); } arr.map(x => x()); // [2,2,2] const arr = []; for (const i of [0, 1, 2]) { arr.push(() => i); } arr.map(x => x()); // [0,1,2] 20 . 20
  • 40. Quindi che uso? const Ogni volta che una variabile non cambia mai il suo valore. (Anche nei loop) È possibile modificare un oggetto che si riferisce a una variabile const let Ogni volta che il valore iniziale di una variabile cambia in seguito var Dimenticala! (finchè si può!) 20 . 21
  • 41. Template literals Utili novità nella produzione delle stringhe 21 . 1
  • 42. Template literals Template literals sono stringhe che possono estendersi su più righe (via backtick) e includere espressioni interpolate (via ${···}) Tagged template literals Una forma più avanzata di costrutto con le quali è possibile modificare l'output delle template literals usando una funzione. 21 . 2
  • 43. TEMPLATE LITERALSTEMPLATE LITERALS const firstName = 'Jane'; console.log(`Hello ${firstName}! it's ${new Date()} The sum is ${10 + 3} How are you today?`); // Output: // Hello Jane! // it's Wed Jul 26 2017 13:13:20 GMT+0200 (CEST) // The sum is 13 // How are you today? 21 . 3
  • 44. TAGGED TEMPLATE LITERALSTAGGED TEMPLATE LITERALS var a = 5; var b = 10; function tag(strings, ...values) { console.log(strings[0]); // "Hello " console.log(strings[1]); // " world " console.log(values[0]); // 15 console.log(values[1]); // 50 } tag`Hello ${ a + b } world ${ a * b }`; //Output: // Hello // world //15 //50 21 . 4
  • 45. Enhanced Object Literals Object literal è una lista di coppie chiave/valore suddivisi da virgola e racchiuso tra {} ES6 ha aggiunto molto zucchero sintattico Method definitions Property value shorthands Computed property keys 22 . 1
  • 46. METHOD DEFINITIONSMETHOD DEFINITIONS //ES6 obj = { foo (a, b) { … }, bar (x, y) { … }, *quux (x, y) { … } }; //ES5 obj = { foo: function (a, b) { … }, bar: function (x, y) { … } // quux: nessun equivalente su ES5 }; //ES5/ES6 obj = { get foo() { … }, set bar(value) { … } }; 22 . 2
  • 47. PROPERTY VALUE SHORTHANDSPROPERTY VALUE SHORTHANDS Se il nome della variabile che specifica il valore della proprietà è uguale chiave di proprietà, è possibile omettere la chiave. const x = 4; const y = 1; const obj = { x: x, y: y }; const obj = { x, y }; function getCar(make, model, value) { return { make, model, _value: value }; } 22 . 3
  • 48. COMPUTED PROPERTY KEYSCOMPUTED PROPERTY KEYS Due strade per specificare la chiave di una proprietà/funzione: via fixed name e via expression const propKey = 'foo'; const obj = { [propKey]: true, ['b'+'ar']: 123 }; console.log(obj.foo); // true const obj = { ['h'+'ello']() { return 'hi'; } }; console.log(obj.hello()); // hi 22 . 4
  • 49. COMPUTED PROPERTY KEYSCOMPUTED PROPERTY KEYS function getCar(make, model, value) { return { // i computed values lavorano anche con // object literals ['make' + make]: true }; } let car = getCar('Kia','Sorento', 10); console.log(car); // { makeKia: true } 22 . 5
  • 50. Destructuring Un modo comodo e conveniente per estrarre valori da array o oggetti in variabili distinte. Object destructuring Array destructuring 23 . 1
  • 51. DESTRUCTURINGDESTRUCTURING var a, b; [a, b] = [1, 2]; console.log(a); // 1 console.log(b); // 2 [a, b, ...rest] = [1, 2, 3, 4, 5]; console.log(a); // 1 console.log(b); // 2 console.log(rest); // [3, 4, 5] ({a, b} = {a:1, b:2}); console.log(a); // 1 console.log(b); // 2 ({a, b, ...rest} = {a:1, b:2, c:3, d:4}); 23 . 2
  • 53. Le basi Nel destructuring sono coinvolte due entità: Destructuring Source I dati da destrutturare. Ad esempio, il valore di un'assegnazione di destrutturazione. Destructuring Target Il modello utilizzato per il destructuring. Ad esempio, le variabili di un'assegnazione di destructuring. 23 . 4
  • 54. In ES6 abbiamo la possibilità di destrutturare il target, utilizzando la source. Nell'assegnazione la chiave è il source ed il value il target let a = {x: 1, y: 2}; let {x:x, y:z} = a; console.log(x) // 1 console.log(z) // 2 let {y} = a; console.log(y) // 2 23 . 5
  • 55. ARRAY DESTRUCTURINGARRAY DESTRUCTURING // Assegnazione semplice di variabile let x = [1, 2, 3, 4, 5]; let [y, z] = x; console.log(y); // 1 console.log(z); // 2 // Assegnazione separata dalla dichiarazione let a, b; [a, b] = [1, 2]; console.log(a); // 1 console.log(b); // 2 23 . 6
  • 56. ARRAY DESTRUCTURINGARRAY DESTRUCTURING Switch di Valori let a = 1; let b = 3; [a, b] = [b, a]; console.log(a); // 3 console.log(b); // 1 23 . 7
  • 57. ARRAY DESTRUCTURINGARRAY DESTRUCTURING Destructuring di un array ritornato da una funzione function f() { return [1, 2]; } let a, b; [a, b] = f(); // puoi fare questo grazie alla destrutturazione // invece di questo a = f()[0]; b = f()[1]; // è la stessa identica cosa, però c'è un enorme differenza //in termini di leggibilità console.log(a); // 1 console.log(b); // 2 23 . 8
  • 58. ARRAY DESTRUCTURINGARRAY DESTRUCTURING Destructuring di un array ritornato da una funzione //Ignorare alcuni valori ritornati function f() { return [1, 2, 3]; } let [a, , b] = f(); console.log(a); // 1 console.log(b); // 3 23 . 9
  • 59. ARRAY DESTRUCTURINGARRAY DESTRUCTURING Assegnazione dei rimanenti valori di un array ad una variabile let [a, ...b] = [1, 2, 3]; console.log(a); // 1 console.log(b); // [2, 3] 23 . 10
  • 60. OBJECT DESTRUCTURINGOBJECT DESTRUCTURING Assegnazione semplice di variabile var o = {p: 42, q: true}; var {p, q} = o; console.log(p); // 42 console.log(q); // true // Assegnazione senza dichiarazione var a, b; ({a, b} = {a:1, b:2}); 23 . 11
  • 61. DEFAULT VALUEDEFAULT VALUE // Default Value è usato se il match sul source è undefined (o mancante). let [a,b = 3, c = 7] = [1, undefined]; // a === 1, b === 3, c === 7 let {x = 1, y = 2, z = 3} = {x: undefined, z: 7} // x === 1, y === 2, z === 7 // Inoltre sono valutati lazily function con() { console.log('test'); return 10; } let [x = con()] = []; //x === 10 con 'test' su console let [x = con()] = [5]; // x === 5 23 . 12
  • 62. L'operatore Rest Elision // Consente di estarre i valori rimanenti in un array let [a,b,...z] = [1, 2, 3, 4, 5, 6]; // Rest Operator - a === 1, b === 2, z === [3,4,5,6] // Consente di utilizzare la sintassi _Array Holes_ // per saltare gli elementi durante la distruzione let [,, ...z] = [1, 2, 3, 4, 5, 6]; // Elision - z === [3,4,5,6] 23 . 13
  • 63. Oggetti annidati e destrutturazione array let metadata = { title: "Scratchpad", translations: [{ locale: "de", localization_tags: [ ], last_edit: "2014-04-14T08:43:37", url: "/de/docs/Tools/Scratchpad", title_translated: "JavaScript-Umgebung" }], url: "/en-US/docs/Tools/Scratchpad" }; let { title: englishTitle, translations: [{ title_translated: localeTitle }] } = metadata; console.log(englishTitle); // "Scratchpad" console.log(localeTitle); // "JavaScript-Umgebung" 23 . 14
  • 64. Iterazione con for...of e destrutturazione var people = [{ name: "Mike Smith", family: { mother: "Jane Smith", father: "Harry Smith", sister: "Samantha Smith" }, age: 35 },{ name: "Tom Jones", family: { mother: "Norah Jones", father: "Richard Jones", brother: "Howard Jones" }, age: 25 }]; for (var {name: n, family: { father: f } } of people) { console.log("Name: " + n + ", Father: " + f); } // "Name: Mike Smith, Father: Harry Smith" // "Name: Tom Jones, Father: Richard Jones" 23 . 15
  • 65. Estrarre campi dagli oggetti passati come parametri di funzioni function userId({id}) { return id; } function whois({displayName: displayName, fullName: {firstName: name}}){ console.log(displayName + " is " + name); } var user = { id: 42, displayName: "jdoe", fullName: { firstName: "John", lastName: "Doe"} }; console.log("userId: " + userId(user)); // "userId: 42" whois(user); // "jdoe is John" 23 . 16
  • 66. Arrow Funcion Una funzione a freccia ha una sintassi più compatta rispetto alla notazione a funzione Usa il lexical scope nell'utilizzo della parola chiave this Sono sempre anonime. È maggiormente indicata per le funzioni piuttosto che con i metodi Non possono essere usate come costruttori Non è solo quindi zucchero sintattico 24 . 1
  • 67. ARROW FUNCTIONARROW FUNCTION function inc(x) { return x + 1; } let inc = x => x + 1; let inc = (x, y) => x + y; let inc = () => 10; let inc = (x) => { console.log(x); return x + 1; } 24 . 2
  • 68. ARROW FUNCTIONARROW FUNCTION (param1, param2, …, paramN) => { statements } (param1, param2, …, paramN) => expression // equivalente a: (param1, param2, …, paramN) => { return expression; } // Le Parentesi sono opzionali se è presente un solo parametro: (singleParam) => { statements } singleParam => { statements } // Una funzione senza parametri richiede comunque le parentesi: () => { statements } () => expression // equivalente a: () => { return expression; } // Il body tra parentesi indica la restituzione di un oggetto: params => ({foo: bar}) 24 . 3
  • 69. ARROW FUNCTIONARROW FUNCTION // Sono supportati ...rest e i parametri di default (param1, param2, ...rest) => { statements } (param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements } // Si può anche destrutturare all'interno della lista dei parametri let f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c; f(); // 6 24 . 4
  • 70. Arrow Funcion - this this context Window Object, global scope Object literals / Constructors Dynamics (per esempio per gli events) Lexical Scope 24 . 5
  • 71. Arrow Funcion - this Lexical scope. Ogni variables/objects/functions definite nel parent scope, sono disponibili nello scope chain ma non viceversa Prima delle arrow function, ogni nuova funzione definiva il proprio this Una arrow function invece non crea il proprio this, e quindi this mantiene il significato che aveva all'interno dello scope genitore. 24 . 6
  • 72. In ECMAScript 3/5, questo problema veniva aggirato assegnando il valore this a una variabile. function Person() { var that = this; that.age = 0; setInterval(function growUp() { that.age++; }, 1000); } 24 . 7
  • 73. Una arrow function invece non crea il proprio this function Person(){ this.age = 0; setInterval(() => { this.age++; // this si riferisce alla proprietà dell'oggetto }, 1000); } var p = new Person(); 24 . 8
  • 74. Altri casi // Una funzione a freccie vuota restituisce undefined let empty = () => {}; (() => "foobar")() // IIAF, restituisce "foobar" // Singolo parametro senza () let simple = a => a > 15 ? 15 : a; simple(16); // 15 simple(10); // 10 // Parametri Multipli con () let max = (a, b) => a > b ? a : b; 24 . 9
  • 75. Altri casi // Più semplice gestire filtering, mapping, ... di array var arr = [5, 6, 13, 0, 1, 18, 23]; var sum = arr.reduce((a, b) => a + b); // 66 var even = arr.filter(v => v % 2 == 0); // [6, 0, 18] var double = arr.map(v => v * 2); // [10, 12, 26, 0, 2, 36, 46] // Le catene di promise sono più concise promise.then(a => { // ... }).then(b => { // ... }); 24 . 10
  • 77. Altri casi // le funzioni a freccia senza parametri sono più semplici da visualizzare setTimeout( () => { console.log("I happen sooner"); setTimeout( () => { console.log("I happen later"); }, 2000); }, 1000); 24 . 13
  • 78. Parameter Handling Il parameter handling ha ricevuto notevoli miglioramenti in ES6. Default parameter values Rest parameters Named parameters via destructuring Spread operator 25 . 1
  • 79. Default Parameters ES6 consente di definire valori di default per i parametri È inoltre possibile sfruttare altre variabili o altri parametri come valori di default 25 . 2
  • 80. DEFAULT PARAMETERSDEFAULT PARAMETERS function f(x, y=0) { return [x, y]; } function foo(x=3, y=x) {} foo(); // x=3; y=3 foo(7); // x=7; y=7 foo(7, 2); // x=7; y=2 const x = 'outer'; function foo(a = x) { const x = 'inner'; console.log(a); // outer } 25 . 3
  • 81. Rest Operator Usando il prefisso ... prima di un ultimo parametro, permette di rappresentare un indefinito numero di argomenti come un array non ci sono parametri a sufficienza, l'operatore rest sarà settato come un empty Array 25 . 4
  • 82. REST OPERATORREST OPERATOR function f(x, ...y) { console.log(x); console.log(y); } f('a', 'b', 'c'); // x = 'a'; y = ['b', 'c'] 25 . 5
  • 83. REST OPERATORREST OPERATOR Rest operator manda in pensione (o quasi) la variabile speciale arguments // ES5: arguments function logAllArguments() { for (var i=0; i < arguments.length; i++) { console.log(arguments[i]); } } // ES6: rest parameter function logAllArguments(...args) { for (const arg of args) { console.log(arg); } } 25 . 6
  • 84. Named Parameters JavaScript non dispone di supporto nativo per i Named Parameteres, ma offre una buona soluzione. Utilizza una object literal per passare i parametri, che sono quindi mappati. Forniscono descrizioni per gli argomenti nelle chiamate di funzione Funzionano bene per i parametri opzionali 25 . 7
  • 85. NAMED PARAMETERSNAMED PARAMETERS // In ES6, puoi usare il destructuring function selectEntries({ start=0, end=-1, step=1 } = {}) { ··· } selectEntries({ step: 2 }); selectEntries({ end: 20, start: 3 }); selectEntries(); //In ECMAScript 5, selectEntries() si dovrebbe invece implementare come: function selectEntries(options) { options = options || {}; var start = options.start || 0; var end = options.end || -1; var step = options.step || 1; ··· } 25 . 8
  • 86. REQUIRED PARAMETERSREQUIRED PARAMETERS // ES5 function foo(mustBeProvided) { if (arguments.length < 1) { throw new Error(); } if (mustBeProvided === undefined) { throw new Error(); } ··· } // ES6 // Chiamata se il parametro è assente function mandatory() { throw new Error('Missing parameter'); } function foo(mustBeProvided = mandatory()) { return mustBeProvided; } 25 . 9
  • 87. The spread operator (...) Lo spread operator somiglia esattamente al rest operator, ma: Rest operator Raccoglie gli elementi restanti di un iterabile in un array e viene utilizzato per rest parameters ed il destructuring Spread operator Trasforma gli elementi di un iterabile in argomenti di una chiamata di funzione o in elementi di un array 25 . 10
  • 88. SPREAD OPERATORSPREAD OPERATOR > Math.max(-1, 5, 11, 3) 11 > Math.max(...[-1, 5, 11, 3]) 11 > Math.max(-1, ...[-1, 5, 11], 3) 11 const arr1 = ['a', 'b']; const arr2 = ['c', 'd']; arr1.push(...arr2); // arr1 ['a', 'b', 'c', 'd'] 25 . 11
  • 89. SPREAD OPERATORSPREAD OPERATOR new Date(...[1912, 11, 24]) const x = ['a', 'b']; const y = ['c']; const z = ['d', 'e']; const arr = [...x, ...y, ...z]; // ['a', 'b', 'c', 'd', 'e'] const set = new Set([11, -1, 6]); const arr = [...set]; // [11, -1, 6] 25 . 12
  • 90. Classes Le classi introdotte in ES6 sono un'evoluzione sintattica in confronto alla versione prototype-based. La sintassi non introduce un nuovo modello di ereditarietà ma una sintassi molto più semplice e pulita per creare oggetti e gestire meglio l'ereditarietà stessa 26 . 1
  • 91. CLASSCLASS class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return `(${this.x}, ${this.y})`; } } var p = new Point(25, 8); p.toString() '(25, 8)' 26 . 2
  • 92. CLASSCLASS var o = { a: 2, m: function(b){ return this.a + 1; } }; console.log(o.m()); // 3 // Chiamando o.m in questo caso, 'this' si riferisce è o.a var p = Object.create(o); // p è un oggetto che eredita da o p.a = 12; // crea una propria property 'a' su p console.log(p.m()); // 13 26 . 3
  • 93. Classes Ereditarietà Singola Metodo Constructor Metodi Statici Getter e Setter Computed method names Ereditarietà Mixin-style Un'importante differenza tra la dichiarazione di una funzione e la dichiarazione di una classe è che le dichiarazioni di funzione sono hoisted, quelle per le classi no. Bisogna dichiarare la classe e poi usarla, altrimenti verrà sollevata un'eccezione 26 . 4
  • 94. Definizione Classe //ES6 class Shape { constructor (id, x, y) { this.id = id; this.move(x, y); } move (x, y) { this.x = x; this.y = y } } //ES5 var Shape = function (id, x, y) { this.id = id; this.move(x, y); }; Shape.prototype.move = function (x, y) { this.x = x; this.y = y; }; 26 . 5
  • 95. Ereditarietà //ES6 class Rectangle extends Shape { constructor (id, x, y, width, height) { super(id, x, y) this.width = width this.height = height } } class Circle extends Shape { constructor (id, x, y, radius) { super(id, x, y) this.radius = radius } } 26 . 6
  • 96. Ereditarietà //ES5 var Rectangle = function (id, x, y, width, height) { Shape.call(this, id, x, y); this.width = width; this.height = height; }; Rectangle.prototype = Object.create(Shape.prototype); Rectangle.prototype.constructor = Rectangle; var Circle = function (id, x, y, radius) { Shape.call(this, id, x, y); this.radius = radius; }; Circle.prototype = Object.create(Shape.prototype); Circle.prototype.constructor = Circle; 26 . 7
  • 97. Super class Cat { constructor(name) { this.name = name; } speak() { console.log(this.name + ' makes a noise.'); } } class Lion extends Cat { speak() { super.speak(); console.log(this.name + ' roars.'); } } 26 . 8
  • 98. Static Methods //ES6 class Rectangle extends Shape { … static defaultRectangle () { return new Rectangle("default", 0, 0, 100, 100) } } class Circle extends Shape { … static defaultCircle () { return new Circle("default", 0, 0, 100) } } var defRectangle = Rectangle.defaultRectangle() var defCircle = Circle.defaultCircle() 26 . 9
  • 99. Static Methods //ES5 var Rectangle = function (id, x, y, width, height) { … }; Rectangle.defaultRectangle = function () { return new Rectangle("default", 0, 0, 100, 100); }; var Circle = function (id, x, y, width, height) { … }; Circle.defaultCircle = function () { return new Circle("default", 0, 0, 100); }; var defRectangle = Rectangle.defaultRectangle(); var defCircle = Circle.defaultCircle(); 26 . 10
  • 100. Getter/Setter //ES6 class Rectangle { constructor (width, height) { this._width = width this._height = height } set width (width) { this._width = width } get width () { return this._width } set height (height) { this._height = height } get height () { return this._height } get area () { return this._width * this._height } } var r = new Rectangle(50, 20) // r.area === 1000 26 . 11
  • 101. Getter/Setter //ES5 var Rectangle = function (width, height) { this._width = width; this._height = height; }; Rectangle.prototype = { set width (width) { this._width = width; }, get width () { return this._width; }, set height (height) { this._height = height; }, get height () { return this._height; }, get area () { return this._width * this._height; } }; var r = new Rectangle(50, 20); // r.area === 1000; 26 . 12
  • 102. Class Expression // unnamed var Polygon = class { constructor(height, width) { this.height = height; this.width = width; } }; // named var Polygon = class Polygon { constructor(height, width) { this.height = height; this.width = width; } }; 26 . 13
  • 103. Ereditarietà Mixin-style class Person { ··· } class Employee extends Person { ··· } class Storage { save(database) { ··· } } class Validation { validate(schema) { ··· } } // Sarebbe bella una ES6 syntax: class Employee extends Storage, Validation, Person { ··· } 26 . 14
  • 104. Ereditarietà Mixin-style const Storage = Sup => class extends Sup { save(database) { ··· } }; const Validation = Sup => class extends Sup { validate(schema) { ··· } }; class Employee extends Storage(Validation(Person)) { ··· } 26 . 15
  • 105. Modules ES6 ha aggiunto finalmente il supporto nativo ai moduli, evitando il ricorso a soluzioni ad hoc e alla implementazione del Module Pattern Secondo le specifiche, un modulo JavaScript è memorizzato in un file: esiste esattamente un modulo per file e un file contiene un solo modulo. 27 . 1
  • 106. MODULE PATTERNMODULE PATTERN var modulo = (function() { function metodoPrivato() { //... } return { metodoPubblico: function() { metodoPrivato(); } } })(); 27 . 2
  • 107. MODULE PATTERNMODULE PATTERN // Import Moduli Esterni var altroModulo = (function() { //... })(); var modulo = (function(moduloEsterno) { function metodoPrivato() { moduloEsterno.metodo(); //... } return { metodoPubblico: function() { metodoPrivato(); } } })(altroModulo); 27 . 3
  • 108. Export //------ 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)); } // È anche possibile esportare più elementi const sqrt = Math.sqrt; function square(x) { return x * x; } function diag(x, y) { return sqrt(square(x) + square(y)); } export {sqrt, square, diag}; 27 . 4
  • 109. Import //------ main.js ------ import { square, diag } from 'lib'; console.log(square(11)); //121 console.log(diag(4,3)); //5 // È possibile usare degli alias //------ main.js ------ import { square, diag as diagonal } from 'lib'; console.log(square(11)); // 121 console.log(diagonal(4, 3)); // 5 // Per importare l'intero modulo: //------ main.js ------ import * as lib from 'lib'; console.log(lib.square(11)); // 121 console.log(lib.diag(4, 3)); // 5 27 . 5
  • 110. Default Export //------ myFunc.js ------ export default function () { ··· } // no semicolon! //------ main1.js ------ import myFunc from 'myFunc'; myFunc(); //------ MyClass.js ------ export default class { ··· } // no semicolon! //------ main2.js ------ import MyClass from 'MyClass'; const inst = new MyClass(); 27 . 6
  • 111. Alcune Note L’importazione e l’esportazione di un modulo sono processi statici Non è possibile importare ed esportare un modulo a runtime in base alla valutazione di determinate condizioni L’importazione di un modulo è soggetta ad hoisting Gli elementi importati da un modulo sono in sola lettura Questa funzionalità non ha ancora un supporto nativo crossbrowser, ma viene implementato in molti traspilers o module bundlers come: Traceur Compiler, Babel, Rollup e Webpack. 27 . 7
  • 112. Alcune Note Ogni modulo viene eseguito una volta completamente caricato. Nei moduli sono presenti dichiarazioni (dichiarazioni variabili, dichiarazioni di funzione, ecc.). Per impostazione predefinita, queste dichiarazioni rimangono locali nel modulo È possibile contrassegnare alcune di esse come export, così che altri moduli possono importarli 27 . 8
  • 113. Alcune Note Un modulo può importare elementi da altri moduli, riferendosi agli altri moduli con stringhe: Relative paths ('../model/user') Absolute paths ('/lib/js/helpers') I Moduli sono singleton. Questo approccio evita le variabili globali, l'unica cosa globale sono i moduli stessi. 27 . 9
  • 114. Array Array.from Converte un array-like object in array Array.of Un nuovo modo di creare array Array.prototype.entries Ritorna un Array Iterator con chiave/valore Array.prototype.keys Ritorna un Array Iterator con chiave Array.prototype.values Ritorna un Array Iterator con valore 28 . 1
  • 115. Array Array.prototype.find Ritorna il valore del primo elemento che soddisfa i requisiti Array.prototype.findIndex Ritorna l'indice del primo elemento che soddisfa i requisiti Array.prototype.fill Popola con un valore statico gli elementi di un array da un indice di partenza ad uno di fine 28 . 2
  • 116. Maps/Sets (Collections) Strutture dati molto comode per gestire insiemi, così da evitare artifici per fare operazioni abbastanza comuni. Sets Un Set può contenere dati di qualsiasi tipo ma senza duplicati. Maps Il Map object è una semplice coppia chiave/valore. Qualunque objects o primitive può essere usato sia come chiave che valore. 29 . 1
  • 117. Maps var myMap = new Map(); var keyString = "a string", keyObj = {}, keyFunc = function () {}; // Setting dei valori myMap.set(keyString, "value associated with 'a string'"); myMap.set(keyObj, "value associated with keyObj"); myMap.set(keyFunc, "value associated with keyFunc"); myMap.size; // 3 29 . 2
  • 118. Maps // Getting dei valori myMap.get(keyString); // "value associated with 'a string'" myMap.get(keyObj); // "value associated with keyObj" myMap.get(keyFunc); // "value associated with keyFunc" myMap.get("a string"); // "value associated with 'a string'" // perchè keyString === 'a string' myMap.get({}); // undefined, perchè keyObj !== {} myMap.get(function() {}) // undefined, perchè keyFunc !== function () {} 29 . 3
  • 119. Sets var mySet = new Set(); mySet.add(1); // Set { 1 } mySet.add(5); // Set { 1, 5 } mySet.add(5); // Set { 1, 5 } mySet.add('some text'); // Set { 1, 5, 'some text' } var o = {a: 1, b: 2}; mySet.add(o); // o si riferisce ad un differente oggetto, quindi è consentito mySet.add({a: 1, b: 2}); 29 . 4
  • 120. Sets mySet.has(1); // true mySet.has(3); // false, 3 non è stato aggiunto al Set mySet.has(5); // true mySet.has(Math.sqrt(25)); // true mySet.has('Some Text'.toLowerCase()); // true mySet.has(o); // true mySet.size; // 5 mySet.delete(5); // Rimuove 5 dal set mySet.has(5); // false, 5 è stato rimosso mySet.size; // 4, abbiamo appena rimosso un valore console.log(mySet); // Set {1, "some text", Object {a: 1, b: 2}, Object {a: 1, b: 2}} 29 . 5
  • 121. Symbol Symbol è una nuova primitiva di ES6 Ogni qualvolta chiamamo la factory function, un nuovo symbol univoco verrà creato. let x = Symbol("mioSimbolo"); Symbols come chiave è una of non-public properties (non sarà restituita da JSON.stringify o getOwnPropertyNames) Un object sarà iterabile se esso avrà un metodo la quale chiave è Symbol.iterator 30 . 1
  • 122. Symbol const symbol1 = Symbol(); > Symbol() === Symbol() false //Symbols può essere usato come chiave di una proprietà: const MY_KEY = Symbol(); const FOO = Symbol(); const obj = {}; 30 . 2
  • 123. Symbol obj[MY_KEY] = 123; //computed property keys console.log(obj[MY_KEY]); // 123 const obj = { data: [ 'hello', 'world' ], [Symbol.iterator]() { ··· } }; for (const x of obj) { console.log(x); } // Output: // hello // world 30 . 3
  • 124. Alcuni usi Identificare un oggetto in maniera univoca assegnando un valore alla sua proprietà id Definizione di enumerazioni (comunemente definiti con interi) Definire una proprietà non visibile nell’elenco delle proprietà dell’oggetto Rendere iterabile una collezione di valori (con l'uso di Symbol.iterator) 30 . 4
  • 125. Iterators e Generators L'elaborazione di ciascuno degli elementi di una collezione è un'operazione molto comune. JavaScript offre diversi modi di iterazione su una raccolta, da semplici for loops a map() e filter(). Iterators e Generators portano il concetto di iterazione direttamente nel core del linguaggio e forniscono un meccanismo per personalizzare, ad esempio, il comportamento di for...of. 31 . 1
  • 126. Iterators Un oggetto è definito Iterator se ha l'abilità di accedere gli elementi di una collezione, uno alla volta e tenere traccia della propria posizione nell'iterazione. Un iteratore possiede il metodo next(), che ritorna il prossimo elemento dell'iterazione. Questo elemento ritornato, è un oggetto con due proprietà: done e value. String, Array, TypedArray, Map, Set, ... sono tutti iterabili predefiniti. 31 . 2
  • 127. Generators I generatori permettono di scrivere una funzione generatore function* nome([param[, param[, ... param]]]) { } che tiene traccia della propria posizione ed ha il metodo next(). I generatori ritornano un oggetto Generator. La parola chiave yield viene usata per mettere in pausa e riprendere l'esecuzione di una funzione generatore. 31 . 3
  • 128. Iterators function makeIterator(array) { var nextIndex = 0; return { next: function() { return nextIndex < array.length ? {value: array[nextIndex++], done: false} : {done: true}; } }; } var it = makeIterator(['yo', 'ya']); console.log(it.next().value); // 'yo' console.log(it.next().value); // 'ya' console.log(it.next().done); // true 31 . 4
  • 129. Iterators (TS) interface Iterable { [Symbol.iterator]() : Iterator; } interface Iterator { next() : IteratorResult; return?(value? : any) : IteratorResult; } interface IteratorResult { value: any; done: boolean; } 31 . 5
  • 130. Iterators function iterateOver(...args) { let index = 0; const iterable = { [Symbol.iterator]() { const iterator = { next() { if (index < args.length) { return { value: args[index++] }; } else { return { done: true }; } } }; return iterator; } } t it bl 31 . 6
  • 131. Iterators // Usando `iterateOver()`: for (const x of iterateOver('fee', 'fi', 'fo', 'fum')) { console.log(x); } // Output: fee, fi, fo, fum 31 . 7
  • 132. Generators function* idMaker() { var index = 0; while(true) yield index++; } var gen = idMaker(); console.log(gen.next().value); // 0 console.log(gen.next().value); // 1 console.log(gen.next().value); // 2 31 . 8
  • 133. Generators function* objectEntries(obj) { const propKeys = Reflect.ownKeys(obj); for (const propKey of propKeys) { // `yield` ritorna un valore e mette in pausa il generator. // Dopo l'esecuzione riprendere da dove era stata messa in pausa yield [propKey, obj[propKey]]; } } const jane = { first: 'Jane', last: 'Doe' }; for (const [key,value] of objectEntries(jane)) { console.log(`${key}: ${value}`); } // Output: // first: Jane // last: Doe 31 . 9
  • 134. Objects Iterabili var oggIterabile = {}; oggIterabile[Symbol.iterator] = function* () { yield 1; yield 2; yield 3; }; for (let valore of oggIterabile) { console.log(valore); } 31 . 10
  • 135. Async JS Le operazioni asincrone sono sempre più comuni e fortunatamente sempre più comode da gestire È finito l'inferno delle callback... benvenuti Promise ed Async/Await Promise ed Async/Await consentono la gestione di operazioni asincrone con semplicità ed enorme potenza espressiva. 32 . 1
  • 136. Promise new Promise(function(resolve, reject) { ... }); Gli oggetti Promise sono usati per computazioni in differita e asincrone. Una Promise rappresenta un'operazione che non è ancora completata, ma lo sarà in futuro. Una Promise rappresenta un proxy per un valore non necessariamente noto quando la promise è stata creata. 32 . 2
  • 137. Promise Una Promise può presentarsi in uno dei seguenti stati: pending (attesa) - stato iniziale, né soddisfatto né respinto. fulfilled (soddisfatto) - significa che l'operazione si è conclusa con sucesso. rejected (respinto) - significa che l'operazione à fallita. 32 . 3
  • 138. Promise let myFirstPromise = new Promise((resolve, reject) => { // Chiamiamo resolve(...) quando viene eseguito correttamente, e reject(... // In questo esempio viene utilizzato setTimeout(...) per simulare un'opera // Nella realtà probabilmente utilizzerai qualcosa del tipo XHR o HTML5 API setTimeout(function(){ resolve("Success!"); // È andato tutto perfettamente! }, 250); }); myFirstPromise.then((successMessage) => { // successMessage viene passato alla funzione resolve(...) . // Non deve essere necessariamente una stringa, ma nel caso sia solo un mes console.log("Yay! " + successMessage); }); 32 . 4
  • 139. Promise fs.readFile('config.json', function (error, text) { if (error) { console.error('Error while reading config file'); } else { try { const obj = JSON.parse(text); console.log(JSON.stringify(obj, null, 4)); } catch (e) { console.error('Invalid JSON in file'); } } }); 32 . 5
  • 140. Promise readFilePromisified('config.json') .then(function (text) { // (A) const obj = JSON.parse(text); console.log(JSON.stringify(obj, null, 4)); }) .catch(function (error) { // (B) // File read error or JSON SyntaxError console.error('An error occurred', error); }); 32 . 6
  • 141. Promise function httpGet(url) { return new Promise( function (resolve, reject) { const request = new XMLHttpRequest(); request.onload = function () { if (this.status === 200) { // Success resolve(this.response); } else { // Something went wrong (404 etc.) reject(new Error(this.statusText)); } }; request.onerror = function () { reject(new Error( 'XMLHttpRequest Error: '+this.statusText)); } 32 . 7
  • 142. Promise httpGet('http://example.com/file.txt') .then( function (value) { console.log('Contents: ' + value); }, function (reason) { console.error('Something went wrong', reason); }); 32 . 8
  • 143. Promise I metodi che fanno la differenza Promise.all Promise.race Promise.resolve Promise.reject 32 . 9
  • 144. Async/Await Una delle più attese novità introdotte da ECMAScript 2017 è stato il supporto di async/await. Si tratta di due parole chiave che abilitano la gestione di funzioni asincrone eseguite tramite un approccio sincrono. Consente la scrittura di codice asincrono pur mantenendo una struttura di codice tipico della programmazione sincrona Si basano sul meccanismo delle Promise e il loro risultato è compatibile con qualsiasi API che utilizza le Promise. 32 . 10
  • 145. Async/Await Async La parola async prima di una funzione significa una cosa semplice: una funzione restituisce sempre una Promise. 32 . 11
  • 146. Async/Await async function f() { return 1; } f().then(alert); // 1 async function f() { return Promise.resolve(1); } f().then(alert); // 1 32 . 12
  • 147. Async/Await async function f() { let promise = new Promise((resolve, reject) => { setTimeout(() => resolve("done!"), 1000) }); let result = await promise; // wait till the promise resolves (*) alert(result); // "done!" } f(); 32 . 13
  • 148. Async/Await function getUtente(userId) { fetch("/utente/" + userId).then(response => { console.log(response); }).catch(error => console.log("Si è verificato un errore!")); } async function getUtente(userId) { try { let response = await fetch("/utente/" + userId); console.log(response); } catch (e) { console.log("Si è verificato un errore!"); } } 32 . 14
  • 149. Async/Await async function getBlogAndPhoto(userId) { try { let utente = await fetch("/utente/" + userId); let blog = await fetch("/blog/" + utente.blogId); let foto = await fetch("/photo/" + utente.albumId); return { utente, blog, foto }; } catch (e) { console.log("Si è verificato un errore!"); } } 32 . 15
  • 151. Ancora su ES6, ES7...ESx Ci vorrebbe un'eternità! Promise & Async/Await RegEx Trailing commas (function parameter) Asynchronous iteration Array/Object/String Updates Rest/Spread Updates BigInt Dynamic Import 33