EcmaScript 2015/2016/...

Historique du standard

Ce qui change avec ES2015

Les prochaines évolutions

"Javascript" est créé en 1995 par Brendan Eich

Mocha -> LiveScript -> Javascript

Microsoft implémente JScript (IE3)

Standardisé en 1996/97 par ECMA : ES1

ES2 en 1998 et ES3 en 1999

ECMAScript : nom du standard

ECMA != W3C

Plusieurs implémentations :

Google : V8

Mozilla : SpiderMonkey

MicroSoft : Chakra

...

TC-39

ECMAScript 4  désaccord du TC-39 entre ES3 et ES4

ECMAScript 3.1 5 fin 2009 puis 5.1 en 2011

ECMAScript "Harmony" : reprise du travail initié par ES4

ECMAScript 6 validé en 2014, spec officielle en juin 2015

ECMAScript 6 devient ES2015 suite à une refonte du processus de décision du TC-39

ES3 1999

ES5 2009

ES2015 2015

10 ans

6 ans

Nouveau processus de validation

Stage 0 : "Strawman" 

Stage 1 : "Proposal" 

Stage 2 : "Draft" 

Stage 3 : "Candidate" 

Stage 4 : "Finished"

Point d'entrée

Proposition officielle

champion identifié

API de haut niveau

Texte de la spec initial

Solution complete et validée

Implémentation possible

Officiellement dans la spec

ES2015

ES6 for fun and profit

arrow functions

classes

enhanced objects literals

template strings

destructuring

default argument

default parameters

rest parameters

spread operator

let + const

iterators

generators

full unicode

modules

map set weakmap weakset

proxies reflects

symbols

binary + octal literals

promises

tail call optimization

for of

Object.assign

Math , object, array , string APIs

Mode strict par defaut

impose des bonnes pratiques

Nouveaux types d'objets : Map Set

const map = new Map();

map.set("foo", 123);

map.get("foo"); // 123

map.has("foo"); //true

map.delete("foo"); //true

map.has("foo"); //false
map.size; //1

map.clear();
map.size; //0

Par rapport aux objets classiques :

nouvelles méthodes

clé peut être de n'importe quelle valeur

Nouveaux types de variables : const et let

//Exemple boucle
for (var i = 0; i < 5; i++) {
  setTimeout(function () {
    console.log(i);
  }, i * 1500);
} // (5) 5


for (let y = 0; y < 5; y++) {
  setTimeout(function () {
    console.log(y);
  }, y * 1500);
} // 0 1 2 3 4 



//Exemple TDZ
function mafonction() {
  console.log(foo);
  // ReferenceError
  let foo = "bar"
}

Par rapport aux var classiques :

portée réduite au block {}

pas de hoisting

Nouveaux types de variables : const et let

const MA_CONSTANTE = 2; //2
MA_CONSTANTE = 4 ; //TypeError: Assignment to constant variable

const monObjet = {
    maValeur : 2
}

monObjet = {
    maValeur : 3
} //TypeError


monObjet.maValeur = 3; // {maValeur:3}

Par rapport aux var classiques :

véritable constante nommée

 immuable ( lien vers référence  valeur )

Nouveaux types de fonctions : arrow function

//Syntaxe
//param => expression
//() => {}

// Idéal pour du fonctionnel
const a = [1,2,3];

const a2 = a.map(function(s){ return s*2});

const a3 = a.map( s => s*2);

//Concerve le "this"
function Personne(){
  this.age = 0;

  setInterval(() => {
    this.age++;
  }, 1000);
}

var p = new Personne();

Par rapport aux fonctions classiques :

ne réécrit pas le this

moins verbeuse, usage orienté fonctionnel

Destructuration (affecter par décomposition )

const user = { first: "Jane", last: "Doe", .... };

const {first, last} = user; 
//first = "Jane" last = "Doe"

const {first: prenom} = getUser(); 
// prenom = "Jane"
function printMyName({ first, last }) {
	return `My name is ${first} ${last}`
}

printMyName(user) //"My name is Jane Doe"
const [a, b] = [1, 2]

const [a, b, ...c] = [1, 2, 3, 4, 5]

const {a, b} = {a:1, b:2}

// Syntaxe ES7 ?
const {a, b, ...rest} = {a:1, b:2, c:3, d:4}  
const {userName} = this.props 

Usage dans react

Arguments de fonction

Valable pour les tableaux et plus généralement les itérables

Modules : import export

// lib/math.js
export function sum(x, y) {
  return x + y;
}
export const pi = 3.141593;


// app.js
import * as math from "lib/math";


// otherApp.js
import {sum, pi} from "lib/math";

structure statique

pas encore d'implémentation officielle pour les loader 



<script>
System.import("myapp").then(function(app) {
  // ...
});
</script>


//Implémentation Edge
<script type="module" src="./app.js">
import { sum } from './math.js';
 //...
</script>

<module>
import app from "myapp";
 //...
</module>
// lib/mathplusplus.js
export * from "lib/math";
export const e = 2.71828182846;
export default function(x) {
    return Math.log(x);
}

// app.js
import ln, {pi, e} from "lib/mathplusplus";

Promesses

fetch("/myData.json")
.then(traitementAsynchrone)
.then(function(myData) {
  console.log(myData);
})

.catch(function(err) {
  //gestion err
});

Specification Promise A+

Chainable

Composable

Parallelisable

Classes 

class Polygone {
  constructor(hauteur, largeur) {
    this.hauteur = hauteur;
    this.largeur = largeur;
  }
}

sucre syntaxique autour de prototype

mots clés courant : extends, super , getter setter, static

Template Literals "Littéraux de gabarits"

`chaîne de texte`

`chaîne ligne 1
 chaîne ligne 2`

`texte ${expression} texte chaîne`

tag `texte ${expression} texte chaîne`

function tag(strings, ...values) {
//...
  return ""
}

possibilité de multi-lignes

tagged template : opportunité pour du DSL

Par rapport aux chaines classiques

Déclaration des objets

function createMonster(name, power) {
  return { type: "Monster", name, power };
}

// en ES5
function createMonster(name, power) {
  return { type: "Monster", name:name, power:power };
}

notation raccourcie

const param = 'size';
const config = {
  [param]: 12,
  ["mobile" + param.charAt(0).toUpperCase() + param.slice(1)]: 4
};

console.log(config); // { size: 12, mobileSize: 4 }

noms de propriétés calculés

Object.assign()

//Object.assign(cible, ...sources)

//Copier un objet
var obj = { a: 1 };
var copie = Object.assign({}, obj);
console.log(copie); // {a: 1}

//fusionner des objets
var o1 = { a: 1 };
var o2 = { b: 2 };
var o3 = { c: 3 };

var obj = Object.assign(o1, o2, o3); // source modifiée
console.log(obj); // { a: 1, b: 2, c: 3 } 

Object.assign({},o1, o2, o3); // { a: 1, b: 2, c: 3 }

Spread, rest

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1.push(...arr2); // [0,1,2,3,4,5]


function union(a, b) {
  return a.concat(b.filter(function (el) {
    return a.indexOf(el) === -1;
  }));
};
 
var c = union(a,b); 

//ES2015
const union = (a, b) => [...new Set([...a, ...b])]; 

spread operator


function fun1(...theArgs) {
  console.log(theArgs.length);
}

fun1();  // 0
fun1(5); // 1
fun1(5, 6, 7); // 3

rest 

Arguments par défaut

function add(x=0, y=0) {
  return x + y;
}

//En ES5
function add(x, y) {
  x = (typeof x !== "undefined" ? x : 0);
  y = (typeof y !== "undefined" ? y : 0);
  return x + y;
}
function selectEntries({ start=0, end=-1, step=1 }) {
    //...
}

arrow functions

classes

enhanced objects literals

template strings

destructuring

default argument

default parameters

rest parameters

spread operator

let + const

iterators

generators

full unicode

modules

map set weakmap weakset

proxies reflects

symbols

binary + octal literals

promises

tail call optimization

for of

Object.assign

Math , object, array , string APIs

Quel support ?

Transpilage vers ES5.1 possible hors proxies

En résumé

ES2015 peut (doit) être utilisé dès maintenant

suivant la cible en natif ou par transpilage avec babel

ES2015 est une énorme évolution de la spec du langage javascript

+ facile, + puissant, + fiable

L'avenir est prometteur

La migration peut se faire par étapes

ES 2016

Array.includes

Opérateur exponentiel

["a", "b", "c"].includes("a") // true
["a", "b", "c"].includes("d") // false
x ** y === Math.pow(x,y)

ES 2017

Object.entries() Object.values()

var obj = { toto: "truc", machin: 42 }; 
Object.entries(obj) // [ ['toto', 'truc'], ['machin', 42] ]
Object.values(obj) // [ 'truc', 42 ]

Stage 3 :

SIMD,

Async,

String padding,

trailing commas in function args

Merci

EcmaScript 2015

By Maxime Warnier

EcmaScript 2015

  • 1,910