Dr.SabinBuragawww.purl.org/net/busaco
programare Web
limbajul JavaScript – aspecte moderne: ES6, ES7,…
www.flickr.com/photos/nathansmith/4704268314/
Dezvoltarea aplicațiilor Web
la nivel de client
Dr.SabinBuragawww.purl.org/net/busaco
“A programming language is low level when
its programs require attention to the irrelevant.”
Alan J. Perlis
Dr.SabinBuragawww.purl.org/net/busaco
Care este prezentul și viitorul
limbajului JavaScript?
Dr.SabinBuragawww.purl.org/net/busaco
ECMAScript 2015 (ES6)
definirea de clase – perspectiva paradigmei obiectuale
parametri cu valori implicite și parametri multipli
machete pentru șiruri de caractere (template literals)
declararea succintă a funcțiilor anonime (arrow functions)
iteratori și generatori
notificări privind rezultatul oferit de o funcție (promises)
noi tipuri de date – e.g., Set, Map, Symbol, Proxy
modularizarea codului: module + importuri
…
Dr.SabinBuragawww.purl.org/net/busaco
lista facilităților + exemplificări:
es6-features.org
ponyfoo.com/articles/es6
Dr.SabinBuragawww.purl.org/net/busaco
Definirea de clase
(perspectiva paradigmei obiectuale)
“simple sugar over the prototype-based OO pattern”
https://ponyfoo.com/articles/es6-classes-in-depth
Dr.SabinBuragawww.purl.org/net/busaco
const DIST = 7, MAXPOWER = 33;
class Robot {
constructor (distance = 0) {
this.power = 0;
this.distance = distance;
}
move () {
if (this.power < 1) {
throw new RangeError ('N-am energie');
}
this.power--;
this.distance += DIST;
}
addPower () {
if (this.power >= MAXPOWER) {
throw new RangeError ('Bateria e plină');
}
this.power++;
}
}
un robot poate fi mutat,
parcurgând o distanță
prestabilită și consumând
o unitate energică
suplimentar, poate fi
alimentat cu energie
în ES6 se pot declara
parametri cu valori implicite
Dr.SabinBuragawww.purl.org/net/busaco
const DIST = 7, MAXPOWER = 33;
class Robot {
constructor (distance = 0) {
this.power = 0;
this.distance = distance;
}
move () {
if (this.power < 1) {
throw new RangeError ('N-am energie');
}
this.power--;
this.distance += DIST;
}
addPower () {
if (this.power >= MAXPOWER) {
throw new RangeError ('Bateria e plină');
}
this.power++;
}
}
// instanțiem un robot
// distanța ia valoarea implicită
let robot = new Robot ();
console.log (robot.distance);
try {
robot.addPower ();
robot.move ();
robot.move ();
} catch (e) {
console.error (e.message);
} finally {
console.log ('M-am deplasat cu '
+ robot.distance +
' metri, iar energia actuală este '
+ robot.power);
}
Dr.SabinBuragawww.purl.org/net/busaco
const DIST = 7, MAXPOWER = 33;
class Robot {
constructor (distance = 0) {
this.power = 0;
this.distance = distance;
}
move () {
if (this.power < 1) {
throw new RangeError ('N-am energie');
}
this.power--;
this.distance += DIST;
}
addPower () {
if (this.power >= MAXPOWER) {
throw new RangeError ('Bateria e plină');
}
this.power++;
}
}
// instanțiem un robot
// distanța ia valoarea implicită
let robot = new Robot ();
console.log (robot.distance);
try {
robot.addPower ();
robot.move ();
robot.move ();
} catch (e) {
console.error (e.message);
} finally {
console.log ('M-am deplasat cu '
+ robot.distance +
' metri, iar energia actuală este '
+ robot.power);
}
Dr.SabinBuragawww.purl.org/net/busaco
class R2D2 extends Robot {
constructor (distance) {
super (distance * 2);
}
move () {
super.move ();
this.power++; // R2D2 nu consumă energie ;)
}
}
mai sunt permise:
extinderi de clasă via extends
acces – cu super – la membrii din clasa de bază
metode de tip get și set
metode statice specificate cu prefixul static (similar C++)
a se vedea arhiva
exemplelor
Dr.SabinBuragawww.purl.org/net/busaco
// instanțiem robotul din clasa R2D2
let r2d2 = new R2D2 (15);
try {
r2d2.addPower (); // inițial, R2D2 trebuie alimentat cu energie
r2d2.move ();
} catch (e) {
console.error (e.message);
}
finally {
console.log ('Sunt R2D2, m-am deplasat cu '
+ r2d2.distance + ' metri, iar energia curentă este ' + r2d2.power);
}
de ce această
valoare?
Dr.SabinBuragawww.purl.org/net/busaco
Noi maniere de a declara variabile
const – valori constante vizibile la nivel de bloc
Dr.SabinBuragawww.purl.org/net/busaco
Noi maniere de a declara variabile
let – alternativă la var, cu vizibilitate la nivel de bloc
(mărginirea domeniului de vizibilitate – scope)
ponyfoo.com/articles/es6-let-const-and-temporal-dead-zone-in-depth
Dr.SabinBuragawww.purl.org/net/busaco
function TestareLet () {
let x = 33;
if (true) {
// variabilă diferită!
let x = 74;
console.log (x); // 74
}
console.log (x); // 33
}
function TestareVar () {
var x = 33;
if (true) {
// aceeași variabilă
var x = 74;
console.log (x); // 74
}
console.log (x); // 74
}
developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/let
Dr.SabinBuragawww.purl.org/net/busaco
verificarea suportului
oferit de navigatoare
vizând o facilitate:
instrumentul Can I Use
https://caniuse.com/
Dr.SabinBuragawww.purl.org/net/busaco
Parametrii unei funcții pot fi multipli
(spread/rest parameters)
const DELIM = 'u2605u2A3C'; // caractere Unicode
function concatenează (...cuvinte) {
return cuvinte.join (DELIM);
}
console.log (concatenează ('ES6', 'e', 'super!')); // "ES6★⨼e★⨼super!"
https://ponyfoo.com/articles/es6-spread-and-butter-in-depth
Dr.SabinBuragawww.purl.org/net/busaco
Dr.SabinBuragawww.purl.org/net/busaco
Destructurare în ES6 (destructuring)
“binds properties to as many variables as you need
and it works with both arrays and objects”
https://ponyfoo.com/articles/es6-destructuring-in-depth
Dr.SabinBuragawww.purl.org/net/busaco
destructurare pentru date de tip Array
// selectarea elementelor dorite dintr-o listă (tablou)
let [ primul, , ultimul ] = [ 'Andrei', 'Diana', Date.now() ];
console.log (primul); // "Andrei"
console.log (ultimul); // data curentă în secunde
Dr.SabinBuragawww.purl.org/net/busaco
destructurare în cazul obiectelor
// oferă – ca obiect – coordonatele geografice pentru Iași
function furnizeazăCoordonate () {
return { lat: 47.16667, long: 27.6 };
}
var { lat, long } = furnizeazăCoordonate ();
console.log (lat);
Dr.SabinBuragawww.purl.org/net/busaco
destructurare în cazul obiectelor
(aici, parametri ai funcțiilor)
// furnizează un număr natural generat aleatoriu dintr-un anumit interval
function genAleator ({ min = 1, max = 300 } = { }) {
return Math.floor (Math.random () * (max - min)) + min;
}
for (let it of [1, 2, 3, 4]) { // 4 numere generate aleatoriu
console.log (genAleator ());
}
rularea programului cu instrumentul interactiv JS Bin
Dr.SabinBuragawww.purl.org/net/busaco
Machete privind substituția de valorile de bază
(template literals)
machetă = orice șir de caractere delimitat de simbolul `
(inclusiv specificat pe mai multe linii de text – multiline)
o machetă poate include expresii JavaScript specificate
cu ${…} ce vor fi înlocuite cu valoarea evaluată
Dr.SabinBuragawww.purl.org/net/busaco
var articol = { // obiect JS oferind date despre un articol
titlu: 'Machete ES6',
subiect: 'facilități privind substituția de valori',
slogan: 'Generare HTML cu JS',
termeni: [ 'ES6', 'JavaScript', 'HTML5' ]
};
var { titlu, subiect, slogan, termeni } = articol; // destructurare
var html = `<article>
<header><h1>${titlu}</h1></header>
<section>
<h2>Articol despre ${subiect}</h2>
<p>${slogan}</p>
</section>
<footer class='subsol'>
<ul>${termeni.map (termen => `<li>${termen}</li>`).join ('nttt')}</ul>
</footer>
</article>`;
console.log (html);
fiecărui element din tabloul termeni îi corespunde
o machetă a cărei valoare va fi un marcaj HTML
Dr.SabinBuragawww.purl.org/net/busaco
alte detalii sunt furnizate de
https://ponyfoo.com/articles/es6-template-strings-in-depth
http://es6-features.org/#StringInterpolation
Dr.SabinBuragawww.purl.org/net/busaco
Arrow functions
declarare succintă a unei funcții anonime
parametri => valoareOferită
nu posedă propriile valori pentru this, arguments, super
https://ponyfoo.com/articles/es6-arrow-functions-in-depth
Dr.SabinBuragawww.purl.org/net/busaco
// funcție anonimă cu un singur argument de intrare
// se întoarce valoarea unei expresii JS
console.log ( [2, 3, 5].map (număr => număr * 7) ); // [14, 21, 35]
// în JavaScript clasic (ES5):
console.log ( [2, 3, 5].map (function (număr) {
return număr * 7;
}) );
Dr.SabinBuragawww.purl.org/net/busaco
// definirea unei funcții recursive în ES6 – aici, factorialul
let factorial = (număr) => {
return număr === 0 ? 1 : număr * factorial (număr - 1);
};
console.log ( factorial (5) ); // 120
Dr.SabinBuragawww.purl.org/net/busaco
// prelucrarea facilă a tablourilor: filtrare, asociere de valori,…
var numere = [1, 7, 50, 74, 9, 85, 51, 12, 7, 15];
// suma tuturor valorilor: 311
var suma = numere.reduce ((a, b) => a + b);
// doar numerele impare: [1, 7, 9, 85, 51, 7, 15]
var impare = numere.filter (val => val % 2 === 1);
// valorile pătratelor
var pătrate = numere.map (val => Math.pow (val, 2));
developer.mozilla.org/Web/JavaScript/Reference/Functions/Arrow_functions
Dr.SabinBuragawww.purl.org/net/busaco
Dr.SabinBuragawww.purl.org/net/busaco
Iteratori
iterarea valorilor se poate realiza asupra oricărui obiect
se pot genera secvențe de valori (finite ori infinite)
prelucrabile via noua construcție for…of
https://ponyfoo.com/articles/es6-iterators-in-depth
Dr.SabinBuragawww.purl.org/net/busaco
// Recurgerea la iteratori pentru a genera secvențe infinite de valori
const VAL = 7, MAX = 69;
let secvMult = { // generează o secvență de nr. multiplicate cu o valoare
[Symbol.iterator]() {
let curent = 0; // contor disponibil doar în interiorul iteratorului
return {
next () { // se expune metoda next () pentru a obține următoarea valoare
curent++;
// metoda next () va întoarce obligatoriu 2 valori
return {
done: false, // 'true' semnalează că secvența se termină
value: curent * VAL // elementul curent al secvenței
};
}
};
}
}
for (let numar of secvMult) {
if (numar > MAX) break; // secvența fiind infinită, trebuie să folosim 'break'
console.log (numar);
}
Dr.SabinBuragawww.purl.org/net/busaco
rezultat al execuției programului JavaScript
de experimentat rularea cu JS Bin
Dr.SabinBuragawww.purl.org/net/busaco
Iteratori
remarcă:
un singur element al secvenței poate fi accesat
la un moment dat (lasy in nature)
Dr.SabinBuragawww.purl.org/net/busaco
Generatori
generator = tip special de iterator ce returnează g
obiecte de tip generator care ulterior pot fi iterate cu
Array.from (g), […g] sau for valoare of g
https://ponyfoo.com/articles/es6-generators-in-depth
http://es6-features.org/#GeneratorFunctionIteratorProtocol
Dr.SabinBuragawww.purl.org/net/busaco
Generatori
oprirea temporară și apoi continuarea execuției
unui generator se realizează via yield
https://developer.mozilla.org/Web/JavaScript/Reference/Operators/yield
Dr.SabinBuragawww.purl.org/net/busaco
// declararea unui generator de identificatori numerici
function* idMaker () {
var index = 0;
while (index < 3)
yield index++;
}
const gen = idMaker ();
// obținerea unui identificator via generatorul declarat
console.log (gen.next ().value); // 0
console.log (gen.next ().value); // 1
console.log (gen.next ().value); // 2
console.log (gen.next ().value); // undefined
// iterarea valorilor de identificatori generați
for (let id of idMaker ()) {
console.log (id);
}
function* declară un generator
apelul idMaker () nu execută corpul
funcției, ci creează un obiect
generator menit a controla
execuția instrucțiunilor din corp
vezi exemplul
din arhivă
Dr.SabinBuragawww.purl.org/net/busaco
// generarea secvenței numerelor lui Fibonacci
let fib = function* (numere) {
let prec = 0, curent = 1;
while (numere-- > 0) {
[ prec, curent ] = [ curent, prec + curent ]; // destructurare
yield curent;
}
}
// primele 10 numere
console.log ([ ...fib (10) ]); // [1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
// al doilea din secvență, apoi restul de la al patrulea încolo
let [ , n2, , ...restul ] = fib (10);
console.log (n2, restul); // 2 și [5, 8, 13, 21, 34, 55, 89]
adaptare după http://es6-features.org/#GeneratorMatching
Dr.SabinBuragawww.purl.org/net/busaco
pentru aspecte avansate, a se studia:
exploringjs.com/es6/ch_generators.html
www.promisejs.org/generators/
Dr.SabinBuragawww.purl.org/net/busaco
Promises
promisiune (promise)  rezultat ce ar putea fi oferit
în urma execuției unei operații asincrone
represents an operation that has not completed yet,
but is expected in the future
developer.mozilla.org/Web/JavaScript/Reference/Global_Objects/Promise
http://exploringjs.com/es6/ch_promises.html
Dr.SabinBuragawww.purl.org/net/busaco
Promises
fiecare obiect de tip Promise
se poate afla în una dintre stările:
pending – stare inițială,
operația nu s-a terminat sau a fost anulată
Dr.SabinBuragawww.purl.org/net/busaco
Promises
fiecare obiect de tip Promise
se poate afla în una dintre stările:
fulfilled – operația s-a terminat cu succes,
oferind un rezultat
Dr.SabinBuragawww.purl.org/net/busaco
Promises
fiecare obiect de tip Promise
se poate afla în una dintre stările:
rejected – operația a eșuat,
oferindu-se un motiv (eroarea survenită)
Dr.SabinBuragawww.purl.org/net/busaco
Promises
fiecare obiect de tip Promise
se poate afla în una dintre stările:
settled – operația a avut loc (cu succes sau cu eroare)
Dr.SabinBuragawww.purl.org/net/busaco
// implementarea unui obiect Promise
var promise = new Promise (function (resolve, reject) {
// realizarea unor operații (eventual, în mod asincron)
// apoi, în funcție de ceea ce s-a întâmplat…
if (/* totul e în regulă */) {
resolve ("A mers!"); // poate fi prelucrat rezultatul cu then()
}
else {
reject (Error ("S-a stricat")); // eroarea poate fi tratată via catch()
}
});
specificația pentru implementarea standardizată:
https://promisesaplus.com/
biblioteci JS: promisesaplus.com/implementations
Dr.SabinBuragawww.purl.org/net/busaco
// implementarea unui obiect Promise
var promise = new Promise (function (resolve, reject) {
// realizarea unor operații (eventual, în mod asincron)
// apoi, în funcție de ceea ce s-a întâmplat…
if (/* totul e în regulă */) {
resolve ("A mers!"); // poate fi prelucrat rezultatul cu then()
}
else {
reject (Error ("S-a stricat")); // eroarea poate fi tratată via catch()
}
});
// utilizarea ulterioară
promise.then (function(result) {
console.log (result); // "A mers!"
}, function(err) {
console.log (err); // Error: "S-a stricat"
});
Dr.SabinBuragawww.purl.org/net/busaco
metodele then () și catch () pot fi înlănțuite
un tutorial, oferind exemple practice:
www.html5rocks.com/en/tutorials/es6/promises/
a se studia și github.com/wbinnssmith/awesome-promises
.then(onFullfilment)
.then()
.catch()
pending pending
settled
async actions
.then(onRejection)
.catch(onRejection)
error handling
…Promise Promise
Dr.SabinBuragawww.purl.org/net/busaco
Dr.SabinBuragawww.purl.org/net/busaco
Noi tipuri de date ES6
Set
Map
WeakSet
WeakMap
Symbol
Proxy
Dr.SabinBuragawww.purl.org/net/busaco
Noi tipuri de date ES6: Set
structură de date iterabilă implementând
conceptul de mulțime (un element apare o singură dată)
proprietate: size – nu se utilizează length
metode: add() delete() clear() entries()
has() forEach() keys() values()
developer.mozilla.org/Web/JavaScript/Reference/Global_Objects/Set
Dr.SabinBuragawww.purl.org/net/busaco
Noi tipuri de date ES6: Map
structură de date iterabilă de tip asociere cheie—valoare
(cheile și valorile pot avea orice tip, inclusiv funcții)
proprietate: size
metode: set() get() delete() clear() entries()
has() forEach() keys() values()
developer.mozilla.org/Web/JavaScript/Reference/Global_Objects/Map
Dr.SabinBuragawww.purl.org/net/busaco
Noi tipuri de date ES6: WeakSet
similar cu Set, dar reprezintă o mulțime de obiecte și
nu de valori arbitrare având diverse tipuri de date
în contrast cu Set, obiectele de tip WeakSet nu pot fi
enumerate, iar referințele la obiecte sunt weak
– dacă nu există referințe la una dintre cheile sale,
obiectul e eliberat din memorie (garbage collection)
Dr.SabinBuragawww.purl.org/net/busaco
Noi tipuri de date ES6: WeakMap
similar cu WeakSet, dar fiecare cheie trebuie să fie obiect
ponyfoo.com/articles/es6-weakmaps-sets-and-weaksets-in-depth
www.sitepoint.com/using-the-new-es6-collections-map-set-weakmap-weakset/
Dr.SabinBuragawww.purl.org/net/busaco
Noi tipuri de date ES6: Symbol
un simbol este un tip de date imutabil ce poate fi folosit
ca identificator unic pentru proprietățile obiectelor
a symbol never clashes with any other property key
(symbol or string)
http://exploringjs.com/es6/ch_symbols.html
Dr.SabinBuragawww.purl.org/net/busaco
const ST_VESEL = Symbol('😀');
const ST_TRIST = Symbol('😞');
const ST_NEUTRU = Symbol('😐');
function oferaStareComplementară (stare) {
switch (stare) {
case ST_VESEL: return ST_TRIST;
case ST_TRIST: return ST_VESEL;
default: throw new Error ('Stare de spirit necunoscută');
}
}
try {
console.log (oferaStareComplementară (ST_TRIST));
// conversia la șir de caractere trebuie realizată explicit
console.log (oferaStareComplementară (ST_VESEL).toString ());
// apelăm funcția având ca argument un simbol nedorit
console.log (oferaStareComplementară (ST_NEUTRU));
} catch (e) {
console.log (e.message);
}
Dr.SabinBuragawww.purl.org/net/busaco
Noi tipuri de date ES6: Proxy
se permite interceptarea și modificarea operațiilor
realizate de obiecte – e.g., proprietăți de tip getter
redefinirea semanticii unor construcții ale limbajului
de programare (intercession) – aspect al meta-programării
http://exploringjs.com/es6/ch_proxies.html
Dr.SabinBuragawww.purl.org/net/busaco
suportul vizând noile tipuri de date ES6
oferit de navigatoarele Web actuale
(FF  Firefox, CH  Chrome, OP  Opera, SF  Safari)
http://kangax.github.io/compat-table/es6/
Dr.SabinBuragawww.purl.org/net/busaco
(în loc de) pauză
Dr.SabinBuragawww.purl.org/net/busaco
Extinderea unor tipuri existente
Number – exprimarea de valori octale și binare
const N404octal = 0o624;
const N404binar = 0b110010100;
console.log (N404octal == N404binar); // true
Dr.SabinBuragawww.purl.org/net/busaco
Extinderea unor tipuri existente
RegExp – noi operatori + opțiuni
http://exploringjs.com/es6/ch_regexp.html
Dr.SabinBuragawww.purl.org/net/busaco
Extinderea unor tipuri existente
String – suport mai bun pentru Unicode
inclusiv internaționalizare
http://exploringjs.com/es6/ch_unicode.html
http://es6-features.org/#UnicodeStringRegExpLiteral
Dr.SabinBuragawww.purl.org/net/busaco
Tablouri respectând un anumit tip de date
typed arrays
utile pentru a manipula în principal date binare:
întregi (cu/fără semn) cu stocare pe 8, 16, 32 de biți
Int8Array Uint8Array Int16Array Int32Array etc.
numere reale reprezentate pe 32 sau 64 de biți
Float32Array Float64Array
http://exploringjs.com/es6/ch_typed-arrays.html
Dr.SabinBuragawww.purl.org/net/busaco
// definim o structură de date pe 24 de octeți, similară celei din limbajul C:
// struct Animal { unsigned long id; char nume[16]; float marime }
class Animal {
constructor (mem = new ArrayBuffer (24)) { // alocăm memoria necesară
this.mem = mem;
};
// gestionarea memoriei corespunzătoare datelor de stocat (un buffer)
set mem (date) { // stocarea datelor în zona de memorie alocată
this._mem = date; // intern, vor fi folosite proprietăți „private”
this._id = new Uint32Array (this._mem, 0, 1);
this._nume = new Uint8Array (this._mem, 4, 16);
this._marime = new Float32Array (this._mem, 20, 1);
}
get mem () { // obținerea datelor stocate
return this._mem;
}
adaptare după http://es6-features.org/#TypedArrays
Dr.SabinBuragawww.purl.org/net/busaco
// metode setter/getter pentru fiecare membru în parte
set id (v) { this._id[0] = v; }
get id () { return this._id[0]; }
set nume (v) { this._nume = v; }
get nume () { return this._nume; }
set marime (v) { this._marime[0] = v; }
get marime () { return this._marime[0]; }
}
let tux = new Animal ();
tux.id = 69;
tux.nume = "Tux";
tux.marime = 15.74;
console.log (`Obiectul ${tux.nume} are identificatorul ${tux.id}
și mărimea ${tux.marime}.`);
adaptare după http://es6-features.org/#TypedArrays
Dr.SabinBuragawww.purl.org/net/busaco
Dr.SabinBuragawww.purl.org/net/busaco
Module
scop: modularizarea + reutilizarea codului-sursă
spre deosebire de JavaScript clasic, unde modularizarea
se baza pe biblioteci externe (CommonJS sau RequireJS
care adoptă AMD – Asynchronous Module Definition),
în ES6 există suport nativ
http://exploringjs.com/es6/ch_modules.html
Dr.SabinBuragawww.purl.org/net/busaco
// --json.js--
function preiaJSON (url, procDate) { // preia de la un URL date JSON
let xhr = new XMLHttpRequest (); // procesate cu funcția procDate
xhr.onload = function () {
procDate (this.responseText)
};
xhr.open ("GET", url, true);
xhr.send ();
}
export function oferăConținut (url, procDate) {
preiaJSON (url, date => procDate (JSON.parse (date)));
}
specificarea unui modul – stocat într-un fișier conform
politicii „one module per file & one file per module” –
ce oferă (exportă) funcționalități
Dr.SabinBuragawww.purl.org/net/busaco
// --json.js--
function preiaJSON (url, procDate) {
let xhr = new XMLHttpRequest ();
xhr.onload = function () {
procDate (this.responseText)
};
xhr.open ("GET", url, true);
xhr.send ();
}
export function oferăConținut (url, procDate) {
preiaJSON (url, date => procDate (JSON.parse (date)));
}
// --main.js-- (utilizarea modulului)
import { oferăConținut } from "json.js";
oferăConținut ("http://undeva.info",
date => { procesează (date); });
aici, importul este identificat prin nume (named import)
Dr.SabinBuragawww.purl.org/net/busaco
Remarci:
importul modulelor se poate realiza oriunde în program
(imports are hoisted)
structura modulelor e statică – nu se pot realiza
importuri/exporturi condiționale
se oferă suport pentru dependențe ciclice
Dr.SabinBuragawww.purl.org/net/busaco
nu toate navigatoarele Web oferă
suport pentru încărcarea modulelor JS
cu <script type="module">…</script>
Dr.SabinBuragawww.purl.org/net/busaco
Instrumente ES6
în principal, convertire ES6ES5
Babel – babeljs.io
Traceur – github.com/google/traceur-compiler
altele la https://github.com/addyosmani/es6-tools
Dr.SabinBuragawww.purl.org/net/busaco
ECMAScript 2016 (ES7)
specificație standardizată – ediția 7 (2016)
www.ecma-international.org/ecma-262/7.0/
Dr.SabinBuragawww.purl.org/net/busaco
ECMAScript 2016 (ES7)
noutate:
operatorul ** (exponent)
let valoareLaCub = val => val ** 3; // Math.pow (val, 3);
Dr.SabinBuragawww.purl.org/net/busaco
ECMAScript 2016 (ES7)
noutate:
verificarea faptului că un element aparține unui tablou
metoda Array.includes ()
Dr.SabinBuragawww.purl.org/net/busaco
ECMAScript 2017 (ES8)
specificație standardizată – ediția 8 (iunie 2017)
www.ecma-international.org/ecma-262/8.0/
Dr.SabinBuragawww.purl.org/net/busaco
ECMAScript 2017 (ES8)
noutate:
funcții asincrone (async functions)
definirea unei funcții asincrone conduce la obținerea
unui obiect de tip AsyncFunction
developer.mozilla.org/Web/JavaScript/Reference/Statements/async_function
Dr.SabinBuragawww.purl.org/net/busaco
Funcții asincrone (async functions)
la apelare, o funcție asincronă oferă un obiect
de tip Promise – acesta e creat la execuția funcției asincrone
Dr.SabinBuragawww.purl.org/net/busaco
Funcții asincrone (async functions)
la apelare, o funcție asincronă oferă un obiect
de tip Promise – acesta e creat la execuția funcției asincrone
este executat corpul funcției – execuția poate fi terminată
permanent via return (succes) ori throw (caz de eroare)
Dr.SabinBuragawww.purl.org/net/busaco
Funcții asincrone (async functions)
la apelare, o funcție asincronă oferă un obiect
de tip Promise – acesta e creat la execuția funcției asincrone
este executat corpul funcției – execuția poate fi terminată
permanent via return (succes) ori throw (caz de eroare)
sau poate fi temporar oprită via await
(uzual, execuția va fi reluată ulterior)
Dr.SabinBuragawww.purl.org/net/busaco
Funcții asincrone (async functions)
programul poate fi notificat atunci când este disponibil
rezultatul unei funcții – obiectul Promise e în starea settled
adică operația a avut loc (cu succes sau cu eroare):
se recurge la metodele then () și, eventual, catch ()
Dr.SabinBuragawww.purl.org/net/busaco
Funcții asincrone (async functions)
programul poate fi notificat atunci când este disponibil
rezultatul unei funcții – obiectul Promise e în starea settled
adică operația a avut loc (cu succes sau cu eroare):
se recurge la metodele then () și, eventual, catch ()
această notificare are loc în mod asincron
http://exploringjs.com/es2016-es2017/ch_async-functions.html
Dr.SabinBuragawww.purl.org/net/busaco
const MAXITER = 7;
async function funcAsinc1 () {
for (let i = 1; i <= MAXITER; i++) {
console.log (`Asincron 1: ${i}`);
};
return "Java";
}
async function funcAsinc2 () {
for (let i = 1; i <= MAXITER; i++) {
console.log (`Asincron 2: ${i}`);
};
return "Script";
}
// deoarece o funcție asincronă întoarce un obiect Promise,
// putem folosi metoda then ();
// pentru a trata erorile se va recurge la catch ()
funcAsincP().then (r => console.log (`Rezultat: ${r}`));
console.log ("Program principal");
async function funcAsincP () {
// se așteaptă execuția ambelor funcții asincrone
const [rez1, rez2] = await Promise.all ([
funcAsinc1 (),
funcAsinc2 (),
]);
return rez1 + rez2;
}
Dr.SabinBuragawww.purl.org/net/busaco
const MAXITER = 7;
async function funcAsinc1 () {
for (let i = 1; i <= MAXITER; i++) {
console.log (`Asincron 1: ${i}`);
};
return "Java";
}
async function funcAsinc2 () {
for (let i = 1; i <= MAXITER; i++) {
console.log (`Asincron 2: ${i}`);
};
return "Script";
}
// deoarece o funcție asincronă întoarce un obiect Promise,
// putem folosi metoda then ();
// pentru a trata erorile se va recurge la catch ()
funcAsincP().then (r => console.log (`Rezultat: ${r}`));
console.log ("Program principal");
async function funcAsincP () {
// se așteaptă execuția ambelor funcții asincrone
const [rez1, rez2] = await Promise.all ([
funcAsinc1 (),
funcAsinc2 (),
]);
return rez1 + rez2;
}
Dr.SabinBuragawww.purl.org/net/busaco
de parcurs și articolul N. Grozev, Await and Async Explained
with Diagrams & Examples (2017):
http://nikgrozev.com/2017/10/01/async-await/
Dr.SabinBuragawww.purl.org/net/busaco
ECMAScript 2017 (ES8)
noutate:
memorie partajată (shared memory)
via obiectul SharedArrayBuffer
+ operații atomice
oferite de obiectul global Atomics
pentru detalii și exemplificări, a se parcurge
exploringjs.com/es2016-es2017/ch_shared-array-buffer.html
Dr.SabinBuragawww.purl.org/net/busaco
compararea facilităților oferite în prezent de versiunile
ECMAScript 2016 și ECMAScript 2017
http://kangax.github.io/compat-table/es2016plus/
Dr.SabinBuragawww.purl.org/net/busaco
Alte resurse – disponibile liber:
Nicholas C. Zakas, Understanding ECMAScript 6 (2015)
https://leanpub.com/understandinges6/read
Axel Rauschmayer, Exploring ES6 (2017)
http://exploringjs.com/es6/index.html
Wolfram Kriesing, ES6 Katas (2016)
http://es6katas.org/
Axel Rauschmayer, Exploring ES2016 & ES2017 (2017)
http://exploringjs.com/es2016-es2017/index.html
Dr.SabinBuragawww.purl.org/net/busaco
ECMAScript 2018 (ES9)
specificație în lucru
https://tc39.github.io/ecma262/
informații de interes la
http://2ality.com/2017/02/ecmascript-2018.html
Dr.SabinBuragawww.purl.org/net/busaco
episodul viitor:
JavaScript în cadrul browser-ului Web

CLIW 2017-2018 (6/12) Limbajul de programare JavaScript. Aspecte moderne: ES6, ES7, ES8

  • 1.
    Dr.SabinBuragawww.purl.org/net/busaco programare Web limbajul JavaScript– aspecte moderne: ES6, ES7,… www.flickr.com/photos/nathansmith/4704268314/ Dezvoltarea aplicațiilor Web la nivel de client
  • 2.
    Dr.SabinBuragawww.purl.org/net/busaco “A programming languageis low level when its programs require attention to the irrelevant.” Alan J. Perlis
  • 3.
  • 4.
    Dr.SabinBuragawww.purl.org/net/busaco ECMAScript 2015 (ES6) definireade clase – perspectiva paradigmei obiectuale parametri cu valori implicite și parametri multipli machete pentru șiruri de caractere (template literals) declararea succintă a funcțiilor anonime (arrow functions) iteratori și generatori notificări privind rezultatul oferit de o funcție (promises) noi tipuri de date – e.g., Set, Map, Symbol, Proxy modularizarea codului: module + importuri …
  • 5.
    Dr.SabinBuragawww.purl.org/net/busaco lista facilităților +exemplificări: es6-features.org ponyfoo.com/articles/es6
  • 6.
    Dr.SabinBuragawww.purl.org/net/busaco Definirea de clase (perspectivaparadigmei obiectuale) “simple sugar over the prototype-based OO pattern” https://ponyfoo.com/articles/es6-classes-in-depth
  • 7.
    Dr.SabinBuragawww.purl.org/net/busaco const DIST =7, MAXPOWER = 33; class Robot { constructor (distance = 0) { this.power = 0; this.distance = distance; } move () { if (this.power < 1) { throw new RangeError ('N-am energie'); } this.power--; this.distance += DIST; } addPower () { if (this.power >= MAXPOWER) { throw new RangeError ('Bateria e plină'); } this.power++; } } un robot poate fi mutat, parcurgând o distanță prestabilită și consumând o unitate energică suplimentar, poate fi alimentat cu energie în ES6 se pot declara parametri cu valori implicite
  • 8.
    Dr.SabinBuragawww.purl.org/net/busaco const DIST =7, MAXPOWER = 33; class Robot { constructor (distance = 0) { this.power = 0; this.distance = distance; } move () { if (this.power < 1) { throw new RangeError ('N-am energie'); } this.power--; this.distance += DIST; } addPower () { if (this.power >= MAXPOWER) { throw new RangeError ('Bateria e plină'); } this.power++; } } // instanțiem un robot // distanța ia valoarea implicită let robot = new Robot (); console.log (robot.distance); try { robot.addPower (); robot.move (); robot.move (); } catch (e) { console.error (e.message); } finally { console.log ('M-am deplasat cu ' + robot.distance + ' metri, iar energia actuală este ' + robot.power); }
  • 9.
    Dr.SabinBuragawww.purl.org/net/busaco const DIST =7, MAXPOWER = 33; class Robot { constructor (distance = 0) { this.power = 0; this.distance = distance; } move () { if (this.power < 1) { throw new RangeError ('N-am energie'); } this.power--; this.distance += DIST; } addPower () { if (this.power >= MAXPOWER) { throw new RangeError ('Bateria e plină'); } this.power++; } } // instanțiem un robot // distanța ia valoarea implicită let robot = new Robot (); console.log (robot.distance); try { robot.addPower (); robot.move (); robot.move (); } catch (e) { console.error (e.message); } finally { console.log ('M-am deplasat cu ' + robot.distance + ' metri, iar energia actuală este ' + robot.power); }
  • 10.
    Dr.SabinBuragawww.purl.org/net/busaco class R2D2 extendsRobot { constructor (distance) { super (distance * 2); } move () { super.move (); this.power++; // R2D2 nu consumă energie ;) } } mai sunt permise: extinderi de clasă via extends acces – cu super – la membrii din clasa de bază metode de tip get și set metode statice specificate cu prefixul static (similar C++) a se vedea arhiva exemplelor
  • 11.
    Dr.SabinBuragawww.purl.org/net/busaco // instanțiem robotuldin clasa R2D2 let r2d2 = new R2D2 (15); try { r2d2.addPower (); // inițial, R2D2 trebuie alimentat cu energie r2d2.move (); } catch (e) { console.error (e.message); } finally { console.log ('Sunt R2D2, m-am deplasat cu ' + r2d2.distance + ' metri, iar energia curentă este ' + r2d2.power); } de ce această valoare?
  • 12.
    Dr.SabinBuragawww.purl.org/net/busaco Noi maniere dea declara variabile const – valori constante vizibile la nivel de bloc
  • 13.
    Dr.SabinBuragawww.purl.org/net/busaco Noi maniere dea declara variabile let – alternativă la var, cu vizibilitate la nivel de bloc (mărginirea domeniului de vizibilitate – scope) ponyfoo.com/articles/es6-let-const-and-temporal-dead-zone-in-depth
  • 14.
    Dr.SabinBuragawww.purl.org/net/busaco function TestareLet (){ let x = 33; if (true) { // variabilă diferită! let x = 74; console.log (x); // 74 } console.log (x); // 33 } function TestareVar () { var x = 33; if (true) { // aceeași variabilă var x = 74; console.log (x); // 74 } console.log (x); // 74 } developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/let
  • 15.
    Dr.SabinBuragawww.purl.org/net/busaco verificarea suportului oferit denavigatoare vizând o facilitate: instrumentul Can I Use https://caniuse.com/
  • 16.
    Dr.SabinBuragawww.purl.org/net/busaco Parametrii unei funcțiipot fi multipli (spread/rest parameters) const DELIM = 'u2605u2A3C'; // caractere Unicode function concatenează (...cuvinte) { return cuvinte.join (DELIM); } console.log (concatenează ('ES6', 'e', 'super!')); // "ES6★⨼e★⨼super!" https://ponyfoo.com/articles/es6-spread-and-butter-in-depth
  • 17.
  • 18.
    Dr.SabinBuragawww.purl.org/net/busaco Destructurare în ES6(destructuring) “binds properties to as many variables as you need and it works with both arrays and objects” https://ponyfoo.com/articles/es6-destructuring-in-depth
  • 19.
    Dr.SabinBuragawww.purl.org/net/busaco destructurare pentru datede tip Array // selectarea elementelor dorite dintr-o listă (tablou) let [ primul, , ultimul ] = [ 'Andrei', 'Diana', Date.now() ]; console.log (primul); // "Andrei" console.log (ultimul); // data curentă în secunde
  • 20.
    Dr.SabinBuragawww.purl.org/net/busaco destructurare în cazulobiectelor // oferă – ca obiect – coordonatele geografice pentru Iași function furnizeazăCoordonate () { return { lat: 47.16667, long: 27.6 }; } var { lat, long } = furnizeazăCoordonate (); console.log (lat);
  • 21.
    Dr.SabinBuragawww.purl.org/net/busaco destructurare în cazulobiectelor (aici, parametri ai funcțiilor) // furnizează un număr natural generat aleatoriu dintr-un anumit interval function genAleator ({ min = 1, max = 300 } = { }) { return Math.floor (Math.random () * (max - min)) + min; } for (let it of [1, 2, 3, 4]) { // 4 numere generate aleatoriu console.log (genAleator ()); } rularea programului cu instrumentul interactiv JS Bin
  • 22.
    Dr.SabinBuragawww.purl.org/net/busaco Machete privind substituțiade valorile de bază (template literals) machetă = orice șir de caractere delimitat de simbolul ` (inclusiv specificat pe mai multe linii de text – multiline) o machetă poate include expresii JavaScript specificate cu ${…} ce vor fi înlocuite cu valoarea evaluată
  • 23.
    Dr.SabinBuragawww.purl.org/net/busaco var articol ={ // obiect JS oferind date despre un articol titlu: 'Machete ES6', subiect: 'facilități privind substituția de valori', slogan: 'Generare HTML cu JS', termeni: [ 'ES6', 'JavaScript', 'HTML5' ] }; var { titlu, subiect, slogan, termeni } = articol; // destructurare var html = `<article> <header><h1>${titlu}</h1></header> <section> <h2>Articol despre ${subiect}</h2> <p>${slogan}</p> </section> <footer class='subsol'> <ul>${termeni.map (termen => `<li>${termen}</li>`).join ('nttt')}</ul> </footer> </article>`; console.log (html); fiecărui element din tabloul termeni îi corespunde o machetă a cărei valoare va fi un marcaj HTML
  • 24.
    Dr.SabinBuragawww.purl.org/net/busaco alte detalii suntfurnizate de https://ponyfoo.com/articles/es6-template-strings-in-depth http://es6-features.org/#StringInterpolation
  • 25.
    Dr.SabinBuragawww.purl.org/net/busaco Arrow functions declarare succintăa unei funcții anonime parametri => valoareOferită nu posedă propriile valori pentru this, arguments, super https://ponyfoo.com/articles/es6-arrow-functions-in-depth
  • 26.
    Dr.SabinBuragawww.purl.org/net/busaco // funcție anonimăcu un singur argument de intrare // se întoarce valoarea unei expresii JS console.log ( [2, 3, 5].map (număr => număr * 7) ); // [14, 21, 35] // în JavaScript clasic (ES5): console.log ( [2, 3, 5].map (function (număr) { return număr * 7; }) );
  • 27.
    Dr.SabinBuragawww.purl.org/net/busaco // definirea uneifuncții recursive în ES6 – aici, factorialul let factorial = (număr) => { return număr === 0 ? 1 : număr * factorial (număr - 1); }; console.log ( factorial (5) ); // 120
  • 28.
    Dr.SabinBuragawww.purl.org/net/busaco // prelucrarea facilăa tablourilor: filtrare, asociere de valori,… var numere = [1, 7, 50, 74, 9, 85, 51, 12, 7, 15]; // suma tuturor valorilor: 311 var suma = numere.reduce ((a, b) => a + b); // doar numerele impare: [1, 7, 9, 85, 51, 7, 15] var impare = numere.filter (val => val % 2 === 1); // valorile pătratelor var pătrate = numere.map (val => Math.pow (val, 2)); developer.mozilla.org/Web/JavaScript/Reference/Functions/Arrow_functions
  • 29.
  • 30.
    Dr.SabinBuragawww.purl.org/net/busaco Iteratori iterarea valorilor sepoate realiza asupra oricărui obiect se pot genera secvențe de valori (finite ori infinite) prelucrabile via noua construcție for…of https://ponyfoo.com/articles/es6-iterators-in-depth
  • 31.
    Dr.SabinBuragawww.purl.org/net/busaco // Recurgerea laiteratori pentru a genera secvențe infinite de valori const VAL = 7, MAX = 69; let secvMult = { // generează o secvență de nr. multiplicate cu o valoare [Symbol.iterator]() { let curent = 0; // contor disponibil doar în interiorul iteratorului return { next () { // se expune metoda next () pentru a obține următoarea valoare curent++; // metoda next () va întoarce obligatoriu 2 valori return { done: false, // 'true' semnalează că secvența se termină value: curent * VAL // elementul curent al secvenței }; } }; } } for (let numar of secvMult) { if (numar > MAX) break; // secvența fiind infinită, trebuie să folosim 'break' console.log (numar); }
  • 32.
    Dr.SabinBuragawww.purl.org/net/busaco rezultat al execuțieiprogramului JavaScript de experimentat rularea cu JS Bin
  • 33.
    Dr.SabinBuragawww.purl.org/net/busaco Iteratori remarcă: un singur elemental secvenței poate fi accesat la un moment dat (lasy in nature)
  • 34.
    Dr.SabinBuragawww.purl.org/net/busaco Generatori generator = tipspecial de iterator ce returnează g obiecte de tip generator care ulterior pot fi iterate cu Array.from (g), […g] sau for valoare of g https://ponyfoo.com/articles/es6-generators-in-depth http://es6-features.org/#GeneratorFunctionIteratorProtocol
  • 35.
    Dr.SabinBuragawww.purl.org/net/busaco Generatori oprirea temporară șiapoi continuarea execuției unui generator se realizează via yield https://developer.mozilla.org/Web/JavaScript/Reference/Operators/yield
  • 36.
    Dr.SabinBuragawww.purl.org/net/busaco // declararea unuigenerator de identificatori numerici function* idMaker () { var index = 0; while (index < 3) yield index++; } const gen = idMaker (); // obținerea unui identificator via generatorul declarat console.log (gen.next ().value); // 0 console.log (gen.next ().value); // 1 console.log (gen.next ().value); // 2 console.log (gen.next ().value); // undefined // iterarea valorilor de identificatori generați for (let id of idMaker ()) { console.log (id); } function* declară un generator apelul idMaker () nu execută corpul funcției, ci creează un obiect generator menit a controla execuția instrucțiunilor din corp vezi exemplul din arhivă
  • 37.
    Dr.SabinBuragawww.purl.org/net/busaco // generarea secvențeinumerelor lui Fibonacci let fib = function* (numere) { let prec = 0, curent = 1; while (numere-- > 0) { [ prec, curent ] = [ curent, prec + curent ]; // destructurare yield curent; } } // primele 10 numere console.log ([ ...fib (10) ]); // [1, 2, 3, 5, 8, 13, 21, 34, 55, 89] // al doilea din secvență, apoi restul de la al patrulea încolo let [ , n2, , ...restul ] = fib (10); console.log (n2, restul); // 2 și [5, 8, 13, 21, 34, 55, 89] adaptare după http://es6-features.org/#GeneratorMatching
  • 38.
    Dr.SabinBuragawww.purl.org/net/busaco pentru aspecte avansate,a se studia: exploringjs.com/es6/ch_generators.html www.promisejs.org/generators/
  • 39.
    Dr.SabinBuragawww.purl.org/net/busaco Promises promisiune (promise) rezultat ce ar putea fi oferit în urma execuției unei operații asincrone represents an operation that has not completed yet, but is expected in the future developer.mozilla.org/Web/JavaScript/Reference/Global_Objects/Promise http://exploringjs.com/es6/ch_promises.html
  • 40.
    Dr.SabinBuragawww.purl.org/net/busaco Promises fiecare obiect detip Promise se poate afla în una dintre stările: pending – stare inițială, operația nu s-a terminat sau a fost anulată
  • 41.
    Dr.SabinBuragawww.purl.org/net/busaco Promises fiecare obiect detip Promise se poate afla în una dintre stările: fulfilled – operația s-a terminat cu succes, oferind un rezultat
  • 42.
    Dr.SabinBuragawww.purl.org/net/busaco Promises fiecare obiect detip Promise se poate afla în una dintre stările: rejected – operația a eșuat, oferindu-se un motiv (eroarea survenită)
  • 43.
    Dr.SabinBuragawww.purl.org/net/busaco Promises fiecare obiect detip Promise se poate afla în una dintre stările: settled – operația a avut loc (cu succes sau cu eroare)
  • 44.
    Dr.SabinBuragawww.purl.org/net/busaco // implementarea unuiobiect Promise var promise = new Promise (function (resolve, reject) { // realizarea unor operații (eventual, în mod asincron) // apoi, în funcție de ceea ce s-a întâmplat… if (/* totul e în regulă */) { resolve ("A mers!"); // poate fi prelucrat rezultatul cu then() } else { reject (Error ("S-a stricat")); // eroarea poate fi tratată via catch() } }); specificația pentru implementarea standardizată: https://promisesaplus.com/ biblioteci JS: promisesaplus.com/implementations
  • 45.
    Dr.SabinBuragawww.purl.org/net/busaco // implementarea unuiobiect Promise var promise = new Promise (function (resolve, reject) { // realizarea unor operații (eventual, în mod asincron) // apoi, în funcție de ceea ce s-a întâmplat… if (/* totul e în regulă */) { resolve ("A mers!"); // poate fi prelucrat rezultatul cu then() } else { reject (Error ("S-a stricat")); // eroarea poate fi tratată via catch() } }); // utilizarea ulterioară promise.then (function(result) { console.log (result); // "A mers!" }, function(err) { console.log (err); // Error: "S-a stricat" });
  • 46.
    Dr.SabinBuragawww.purl.org/net/busaco metodele then ()și catch () pot fi înlănțuite un tutorial, oferind exemple practice: www.html5rocks.com/en/tutorials/es6/promises/ a se studia și github.com/wbinnssmith/awesome-promises .then(onFullfilment) .then() .catch() pending pending settled async actions .then(onRejection) .catch(onRejection) error handling …Promise Promise
  • 47.
  • 48.
    Dr.SabinBuragawww.purl.org/net/busaco Noi tipuri dedate ES6 Set Map WeakSet WeakMap Symbol Proxy
  • 49.
    Dr.SabinBuragawww.purl.org/net/busaco Noi tipuri dedate ES6: Set structură de date iterabilă implementând conceptul de mulțime (un element apare o singură dată) proprietate: size – nu se utilizează length metode: add() delete() clear() entries() has() forEach() keys() values() developer.mozilla.org/Web/JavaScript/Reference/Global_Objects/Set
  • 50.
    Dr.SabinBuragawww.purl.org/net/busaco Noi tipuri dedate ES6: Map structură de date iterabilă de tip asociere cheie—valoare (cheile și valorile pot avea orice tip, inclusiv funcții) proprietate: size metode: set() get() delete() clear() entries() has() forEach() keys() values() developer.mozilla.org/Web/JavaScript/Reference/Global_Objects/Map
  • 51.
    Dr.SabinBuragawww.purl.org/net/busaco Noi tipuri dedate ES6: WeakSet similar cu Set, dar reprezintă o mulțime de obiecte și nu de valori arbitrare având diverse tipuri de date în contrast cu Set, obiectele de tip WeakSet nu pot fi enumerate, iar referințele la obiecte sunt weak – dacă nu există referințe la una dintre cheile sale, obiectul e eliberat din memorie (garbage collection)
  • 52.
    Dr.SabinBuragawww.purl.org/net/busaco Noi tipuri dedate ES6: WeakMap similar cu WeakSet, dar fiecare cheie trebuie să fie obiect ponyfoo.com/articles/es6-weakmaps-sets-and-weaksets-in-depth www.sitepoint.com/using-the-new-es6-collections-map-set-weakmap-weakset/
  • 53.
    Dr.SabinBuragawww.purl.org/net/busaco Noi tipuri dedate ES6: Symbol un simbol este un tip de date imutabil ce poate fi folosit ca identificator unic pentru proprietățile obiectelor a symbol never clashes with any other property key (symbol or string) http://exploringjs.com/es6/ch_symbols.html
  • 54.
    Dr.SabinBuragawww.purl.org/net/busaco const ST_VESEL =Symbol('😀'); const ST_TRIST = Symbol('😞'); const ST_NEUTRU = Symbol('😐'); function oferaStareComplementară (stare) { switch (stare) { case ST_VESEL: return ST_TRIST; case ST_TRIST: return ST_VESEL; default: throw new Error ('Stare de spirit necunoscută'); } } try { console.log (oferaStareComplementară (ST_TRIST)); // conversia la șir de caractere trebuie realizată explicit console.log (oferaStareComplementară (ST_VESEL).toString ()); // apelăm funcția având ca argument un simbol nedorit console.log (oferaStareComplementară (ST_NEUTRU)); } catch (e) { console.log (e.message); }
  • 55.
    Dr.SabinBuragawww.purl.org/net/busaco Noi tipuri dedate ES6: Proxy se permite interceptarea și modificarea operațiilor realizate de obiecte – e.g., proprietăți de tip getter redefinirea semanticii unor construcții ale limbajului de programare (intercession) – aspect al meta-programării http://exploringjs.com/es6/ch_proxies.html
  • 56.
    Dr.SabinBuragawww.purl.org/net/busaco suportul vizând noiletipuri de date ES6 oferit de navigatoarele Web actuale (FF  Firefox, CH  Chrome, OP  Opera, SF  Safari) http://kangax.github.io/compat-table/es6/
  • 57.
  • 58.
    Dr.SabinBuragawww.purl.org/net/busaco Extinderea unor tipuriexistente Number – exprimarea de valori octale și binare const N404octal = 0o624; const N404binar = 0b110010100; console.log (N404octal == N404binar); // true
  • 59.
    Dr.SabinBuragawww.purl.org/net/busaco Extinderea unor tipuriexistente RegExp – noi operatori + opțiuni http://exploringjs.com/es6/ch_regexp.html
  • 60.
    Dr.SabinBuragawww.purl.org/net/busaco Extinderea unor tipuriexistente String – suport mai bun pentru Unicode inclusiv internaționalizare http://exploringjs.com/es6/ch_unicode.html http://es6-features.org/#UnicodeStringRegExpLiteral
  • 61.
    Dr.SabinBuragawww.purl.org/net/busaco Tablouri respectând unanumit tip de date typed arrays utile pentru a manipula în principal date binare: întregi (cu/fără semn) cu stocare pe 8, 16, 32 de biți Int8Array Uint8Array Int16Array Int32Array etc. numere reale reprezentate pe 32 sau 64 de biți Float32Array Float64Array http://exploringjs.com/es6/ch_typed-arrays.html
  • 62.
    Dr.SabinBuragawww.purl.org/net/busaco // definim ostructură de date pe 24 de octeți, similară celei din limbajul C: // struct Animal { unsigned long id; char nume[16]; float marime } class Animal { constructor (mem = new ArrayBuffer (24)) { // alocăm memoria necesară this.mem = mem; }; // gestionarea memoriei corespunzătoare datelor de stocat (un buffer) set mem (date) { // stocarea datelor în zona de memorie alocată this._mem = date; // intern, vor fi folosite proprietăți „private” this._id = new Uint32Array (this._mem, 0, 1); this._nume = new Uint8Array (this._mem, 4, 16); this._marime = new Float32Array (this._mem, 20, 1); } get mem () { // obținerea datelor stocate return this._mem; } adaptare după http://es6-features.org/#TypedArrays
  • 63.
    Dr.SabinBuragawww.purl.org/net/busaco // metode setter/getterpentru fiecare membru în parte set id (v) { this._id[0] = v; } get id () { return this._id[0]; } set nume (v) { this._nume = v; } get nume () { return this._nume; } set marime (v) { this._marime[0] = v; } get marime () { return this._marime[0]; } } let tux = new Animal (); tux.id = 69; tux.nume = "Tux"; tux.marime = 15.74; console.log (`Obiectul ${tux.nume} are identificatorul ${tux.id} și mărimea ${tux.marime}.`); adaptare după http://es6-features.org/#TypedArrays
  • 64.
  • 65.
    Dr.SabinBuragawww.purl.org/net/busaco Module scop: modularizarea +reutilizarea codului-sursă spre deosebire de JavaScript clasic, unde modularizarea se baza pe biblioteci externe (CommonJS sau RequireJS care adoptă AMD – Asynchronous Module Definition), în ES6 există suport nativ http://exploringjs.com/es6/ch_modules.html
  • 66.
    Dr.SabinBuragawww.purl.org/net/busaco // --json.js-- function preiaJSON(url, procDate) { // preia de la un URL date JSON let xhr = new XMLHttpRequest (); // procesate cu funcția procDate xhr.onload = function () { procDate (this.responseText) }; xhr.open ("GET", url, true); xhr.send (); } export function oferăConținut (url, procDate) { preiaJSON (url, date => procDate (JSON.parse (date))); } specificarea unui modul – stocat într-un fișier conform politicii „one module per file & one file per module” – ce oferă (exportă) funcționalități
  • 67.
    Dr.SabinBuragawww.purl.org/net/busaco // --json.js-- function preiaJSON(url, procDate) { let xhr = new XMLHttpRequest (); xhr.onload = function () { procDate (this.responseText) }; xhr.open ("GET", url, true); xhr.send (); } export function oferăConținut (url, procDate) { preiaJSON (url, date => procDate (JSON.parse (date))); } // --main.js-- (utilizarea modulului) import { oferăConținut } from "json.js"; oferăConținut ("http://undeva.info", date => { procesează (date); }); aici, importul este identificat prin nume (named import)
  • 68.
    Dr.SabinBuragawww.purl.org/net/busaco Remarci: importul modulelor sepoate realiza oriunde în program (imports are hoisted) structura modulelor e statică – nu se pot realiza importuri/exporturi condiționale se oferă suport pentru dependențe ciclice
  • 69.
    Dr.SabinBuragawww.purl.org/net/busaco nu toate navigatoareleWeb oferă suport pentru încărcarea modulelor JS cu <script type="module">…</script>
  • 70.
    Dr.SabinBuragawww.purl.org/net/busaco Instrumente ES6 în principal,convertire ES6ES5 Babel – babeljs.io Traceur – github.com/google/traceur-compiler altele la https://github.com/addyosmani/es6-tools
  • 71.
    Dr.SabinBuragawww.purl.org/net/busaco ECMAScript 2016 (ES7) specificațiestandardizată – ediția 7 (2016) www.ecma-international.org/ecma-262/7.0/
  • 72.
    Dr.SabinBuragawww.purl.org/net/busaco ECMAScript 2016 (ES7) noutate: operatorul** (exponent) let valoareLaCub = val => val ** 3; // Math.pow (val, 3);
  • 73.
    Dr.SabinBuragawww.purl.org/net/busaco ECMAScript 2016 (ES7) noutate: verificareafaptului că un element aparține unui tablou metoda Array.includes ()
  • 74.
    Dr.SabinBuragawww.purl.org/net/busaco ECMAScript 2017 (ES8) specificațiestandardizată – ediția 8 (iunie 2017) www.ecma-international.org/ecma-262/8.0/
  • 75.
    Dr.SabinBuragawww.purl.org/net/busaco ECMAScript 2017 (ES8) noutate: funcțiiasincrone (async functions) definirea unei funcții asincrone conduce la obținerea unui obiect de tip AsyncFunction developer.mozilla.org/Web/JavaScript/Reference/Statements/async_function
  • 76.
    Dr.SabinBuragawww.purl.org/net/busaco Funcții asincrone (asyncfunctions) la apelare, o funcție asincronă oferă un obiect de tip Promise – acesta e creat la execuția funcției asincrone
  • 77.
    Dr.SabinBuragawww.purl.org/net/busaco Funcții asincrone (asyncfunctions) la apelare, o funcție asincronă oferă un obiect de tip Promise – acesta e creat la execuția funcției asincrone este executat corpul funcției – execuția poate fi terminată permanent via return (succes) ori throw (caz de eroare)
  • 78.
    Dr.SabinBuragawww.purl.org/net/busaco Funcții asincrone (asyncfunctions) la apelare, o funcție asincronă oferă un obiect de tip Promise – acesta e creat la execuția funcției asincrone este executat corpul funcției – execuția poate fi terminată permanent via return (succes) ori throw (caz de eroare) sau poate fi temporar oprită via await (uzual, execuția va fi reluată ulterior)
  • 79.
    Dr.SabinBuragawww.purl.org/net/busaco Funcții asincrone (asyncfunctions) programul poate fi notificat atunci când este disponibil rezultatul unei funcții – obiectul Promise e în starea settled adică operația a avut loc (cu succes sau cu eroare): se recurge la metodele then () și, eventual, catch ()
  • 80.
    Dr.SabinBuragawww.purl.org/net/busaco Funcții asincrone (asyncfunctions) programul poate fi notificat atunci când este disponibil rezultatul unei funcții – obiectul Promise e în starea settled adică operația a avut loc (cu succes sau cu eroare): se recurge la metodele then () și, eventual, catch () această notificare are loc în mod asincron http://exploringjs.com/es2016-es2017/ch_async-functions.html
  • 81.
    Dr.SabinBuragawww.purl.org/net/busaco const MAXITER =7; async function funcAsinc1 () { for (let i = 1; i <= MAXITER; i++) { console.log (`Asincron 1: ${i}`); }; return "Java"; } async function funcAsinc2 () { for (let i = 1; i <= MAXITER; i++) { console.log (`Asincron 2: ${i}`); }; return "Script"; } // deoarece o funcție asincronă întoarce un obiect Promise, // putem folosi metoda then (); // pentru a trata erorile se va recurge la catch () funcAsincP().then (r => console.log (`Rezultat: ${r}`)); console.log ("Program principal"); async function funcAsincP () { // se așteaptă execuția ambelor funcții asincrone const [rez1, rez2] = await Promise.all ([ funcAsinc1 (), funcAsinc2 (), ]); return rez1 + rez2; }
  • 82.
    Dr.SabinBuragawww.purl.org/net/busaco const MAXITER =7; async function funcAsinc1 () { for (let i = 1; i <= MAXITER; i++) { console.log (`Asincron 1: ${i}`); }; return "Java"; } async function funcAsinc2 () { for (let i = 1; i <= MAXITER; i++) { console.log (`Asincron 2: ${i}`); }; return "Script"; } // deoarece o funcție asincronă întoarce un obiect Promise, // putem folosi metoda then (); // pentru a trata erorile se va recurge la catch () funcAsincP().then (r => console.log (`Rezultat: ${r}`)); console.log ("Program principal"); async function funcAsincP () { // se așteaptă execuția ambelor funcții asincrone const [rez1, rez2] = await Promise.all ([ funcAsinc1 (), funcAsinc2 (), ]); return rez1 + rez2; }
  • 83.
    Dr.SabinBuragawww.purl.org/net/busaco de parcurs șiarticolul N. Grozev, Await and Async Explained with Diagrams & Examples (2017): http://nikgrozev.com/2017/10/01/async-await/
  • 84.
    Dr.SabinBuragawww.purl.org/net/busaco ECMAScript 2017 (ES8) noutate: memoriepartajată (shared memory) via obiectul SharedArrayBuffer + operații atomice oferite de obiectul global Atomics pentru detalii și exemplificări, a se parcurge exploringjs.com/es2016-es2017/ch_shared-array-buffer.html
  • 85.
    Dr.SabinBuragawww.purl.org/net/busaco compararea facilităților oferiteîn prezent de versiunile ECMAScript 2016 și ECMAScript 2017 http://kangax.github.io/compat-table/es2016plus/
  • 86.
    Dr.SabinBuragawww.purl.org/net/busaco Alte resurse –disponibile liber: Nicholas C. Zakas, Understanding ECMAScript 6 (2015) https://leanpub.com/understandinges6/read Axel Rauschmayer, Exploring ES6 (2017) http://exploringjs.com/es6/index.html Wolfram Kriesing, ES6 Katas (2016) http://es6katas.org/ Axel Rauschmayer, Exploring ES2016 & ES2017 (2017) http://exploringjs.com/es2016-es2017/index.html
  • 87.
    Dr.SabinBuragawww.purl.org/net/busaco ECMAScript 2018 (ES9) specificațieîn lucru https://tc39.github.io/ecma262/ informații de interes la http://2ality.com/2017/02/ecmascript-2018.html
  • 88.