Lors du “Hand’s on” ECMAScript6 au BDX IO (http://www.bdx.io), Philippe Charrière nous a présenté les nouveautés de cette version “Harmony” qui est le futur de Javascript.
ECMAScript est un langage de type script standardisé par Ecma International dans le cadre de la spécification ECMA-262. Il s’agit donc d’un standard, dont les spécifications sont mises en œuvre dans différents langages de script, comme JavaScript ou ActionScript.
Même si cette spécification ne sera officialisée que début 2015, de nombreux navigateurs (les vrais quoi… #noTrollInside) comprennent déjà certaines fonctionnalités d’ECMAScript6. Voici un lien pour voir les fonctionnalités déjà implémentées par votre navigateur préféré : http://kangax.github.io/compat-table/es6/
Let’s do it !
Le nouveau mot clé let permet de déclarer des variables locales à un bloc, ce qui permet d’éviter les conflits potentiels avec des variables globales.
function varTest() { var x = 31; if (true) { var x = 71; // same variable! console.log(x); // 71 } console.log(x); // 71 } function letTest() { let x = 31; if (true) { let x = 71; // different variable console.log(x); // 71 } console.log(x); // 31 }
Arguments par défaut
Les fonctions acceptent des valeurs par défaut pour leurs arguments :
function myFct(foo = “bar” ) { }
Construction des chaînes
On peut construire les chaînes de caractères avec interpolation. Plus la peine de concaténer toutes ces chaînes et variables ! C’est le caractère ` (accent grave ou back-tick) qui permet l’interpolation (comme en shell script).
let message = Hello ${world}
On peut aussi construire des chaînes sur plusieurs lignes :
let string = ligne 1 ligne 2
;
Ou faire des “Tagged template Strings” :
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 return "Bazinga!"; } tagHello ${ a + b } world ${ a * b}
; // "Bazinga!"
Déstructuration
Avec la déstructuration, on peut extraire les données de tableau ou d’objets comme si on déclarait des tableaux ou objets.
Un petit exemple :
var foo = ["one", "two", "three"]; // without destructuring var one = foo[0]; var two = foo[1]; var three = foo[2]; // with destructuring var [one, two, three] = foo;
On peut aussi se servir de cette syntaxe pour faire des opérations sur des tableaux :
var a = 1; var b = 3; [a, b] = [b, a]; //a=3 et b=1
Ou pour retourner plusieurs valeurs d’une fonction :
function f() { return [1, 2]; }
var a, b; [a, b] = f(); console.log("A is " + a + " B is " + b); // A is 1 B is 2
var a = f(); console.log("A is " + a); //tableau contenant les valeurs 1 et 2
Boucle for…of
Contrairement à for…in qui boucle sur les clés, for…of boucle sur les valeurs :
let arr = [ 3, 5, 7 ]; for (let i in arr) { console.log(i); // logs "0", "1", "2" } for (let i of arr) { console.log(i); // logs "3", "5", "7" }
Promises
Les “promises” servent à faire des exécutions différées et asychrones. Une promise est dans un des états suivants :
- pending : état initial, ni exécuté, ni rejeté
- fulfilled : exécuté avec succès
- rejected : exécution échouée
- settled : exécutée, avec succès ou en échec
Cela va remplacer nos gestions d’events et de callback à coups de addEventListener(‘error’) ou addEventListener(‘load’). Cela est un peu implémenté par JQuery par exemple avec ses objets Deferred et Promise.
La construction de base est la suivante :
var promise = new Promise(function(resolve, reject) { // do a thing, possibly async, then… if (/* everything turned out fine */) { resolve("Stuff worked!"); } else { reject("It broke"); } });
Une promise prend 2 arguments qui seront les callbacks en cas de succès et d’échec.
Ensuite pour exécuter la promise :
promise.then(function(result) { console.log(result); // "Stuff worked!" }, function(err) { console.log(err); // "It broke" });
Classes
Une nouvelle (vraie) écriture des classes est proposée :
class Dog { constructor (name="cookie") { /* mot-clé constructor + valeurs par défaut / this.name = name; / propriétés définies dans le constructeur / } wouaf () { / pas de mot-clé function */ console.log(this.name + ": wouaf! wouaf!"); } } wolf = new Dog(); wolf.wouaf()
On peut bien sûr hériter d’une classe :
class Animal { constructor(name) { this.name = name; } } class Dog extends Animal { constructor (name="cookie") { super(name) /* on appelle le constructeur de la classe mère */ } wouaf () { console.log(this.name + ": wouaf! wouaf!"); } }
Arrow function
On peut définir des fonctions avec une double flèche =>
([param] [, param]) => { statements } ou param => expression
Exemple :
var complex = (a, b) => { if (a > b) { return a; } else { return b; } }
ou
var sayHello = (...people) => people.forEach((somebody) => console.log("Hello", somebody)); sayHello("Bob Morane", "John Doe", "Jane Doe");
Une bonne chose de ces “arrow function” est la gestion du this ! Avant, on devait bidouiller pour que le this référence la bonne valeur :
//Avant function Animal(friends) { this.friends = friends; this.hello = function(friend) { console.log("hello " + friend); } this.helloAll = function() { this.friends.forEach(function(friend) { this.hello(friend); /* erreur ! This reférence la nouvelle fonction pas l’objet Animal */ }); } }
//Contournement function Animal(friends) { this.friends = friends; this.hello = function(friend) { console.log("hello " + friend); } this.helloAll = function() { this.friends.forEach(function(friend) { this.hello(friend); }.bind(this)); // ou var that = this; dans Animal et ensuite that.hello(friend); } }
//Avec ECMAScritp6 class Animal { constructor (friends=[]) { this.friends = friends; } hello(friend) { console.log("hello " + friend); } helloAll() { this.friends.forEach((friend) => this.hello(friend)); //this référence bien l’objet Animal } }
Conclusion
Et plein d’autres choses bien sûr ! Tout ici : http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts
Pas mal de nouveautés intéressantes donc pour cette nouvelle spécification. Un peu comme HTML5 il va falloir attendre un peu pour que cela soit standardisé dans tous les navigateurs, mais on peut déjà voir quelques unes de ces nouveautés dans différents navigateurs.
BDX.IO a eu lieu pour la première fois le 17 Octobre à Bordeaux, avec 300 participants et une quarantaine de speakers. Rendez-vous l’année prochaine pour une conférence encore plus grande on l’espère, et à très vite sur ce blog pour d’autres retours sur le BDX.IO.