ECMAScript 2022
Usage
1. Compatibilité
ES est l’abréviation pour ECMAScript. Les versions JavaScript reposaient sur un numéro qui a été remplacé par l’année de mise à jour.
Nous avons donc les versions suivantes :
Ancienne numérotation |
Nouvelle numérotation |
ES6 |
ES2015 |
ES7 |
ES2016 |
ES8 |
ES2017 |
ES9 |
ES2018 |
ES10 |
ES2019 |
ES11 |
ES2020 |
ES12 |
ES2021 |
ES13… |
ES2022… |
L’ES6 ou bien ES2015 précédemment appelé ECMAScript 6 est disponible avec tous les navigateurs récents : Chrome, Firefox, Edge, Safari, Opera. Il n’est en revanche pas disponible sur Internet Explorer (ancêtre de Edge) mais la part de marché de ce navigateur décroît régulièrement pour être aujourd’hui inférieure à 2 %. Il est également bien pris en compte sur mobile.
Le site web https://kangax.github.io/compat-table/es2016plus/ indique la compatibilité des navigateurs selon les versions de JavaScript. Comme vous pouvez le constater, la compatibilité jusqu’à la version 2022 est bien présente pour les versions récentes de Microsoft Edge, Chrome et Firefox.
Il est donc possible dès maintenant d’utiliser l’ES2022 pour des sites grand public. Pour rester compatible avec des navigateurs anciens, il est possible de mettre en place une librairie JavaScript avec moins de fonctionnalités sans gêner le fonctionnement du site. Pour cela, on testera dès le chargement de la page la version du navigateur, on prendra en compte alors en fonction du résultat la bonne librairie.
La première librairie offrira un service minimum pour faire fonctionner le site avec Internet Explorer.
// jib.js
document.body.onload = function() { alert( "Version simple" ); };
La deuxième librairie offrira le service complet pour tous les navigateurs compatibles 2022.
// lib2022.js
document.body.onload = function() { alert( "Version optimale" ); };
Il reste ensuite à détecter le navigateur courant à l’aide de la propriété window.navigator.userAgent et à charger en conséquence le bon script.
<!DOCTYPE html>
<html>
<head>
<script>
var...
Structure de données plus efficace
1. Chaînes de caractères
De nouveaux traitements sont disponibles sur les chaînes de caractères :
-
repeat pour dupliquer une chaîne.
-
startsWith pour indiquer si une chaîne commence par une valeur.
-
endsWith pour indiquer si une chaîne se termine par une valeur.
-
includes pour savoir si une chaîne contient une autre chaîne.
alert( "bonjour".repeat( 2 ) ); // « bonjourbonjour »
alert( "bonjour".startsWith( "bon" ) ); // vrai
alert( "bonjour".endsWith( "jour" ) ); // vrai
alert( "bonjour".includes( "jou" ) ); // vrai
Il est possible de définir une chaîne sur plusieurs lignes avec d’éventuels paramètres en l’encadrant par le caractère `. Les paramètres sont définis par la syntaxe ${valeur}.
let voiture = { marque : "renault", modele : "clio" };
let msg = `Vous êtes propriétaire d'une voiture
de marque ${voiture.marque} et de modèle ${voiture.modele}`;
alert( msg );
2. Collections
Il est possible de stocker un ensemble de valeurs uniques grâce à la classe Set. Parmi les principales méthodes, nous aurons :
-
add pour ajouter une valeur.
-
delete pour...
Développement objet rapide
1. Classes
Comme nous l’avons vu jusqu’ici, JavaScript n’est pas complètement un langage objet car tout repose sur une propriété prototype pour partager entre différents objets d’une classe les mêmes fonctions. Nous avons vu également qu’une fonction a un rôle ambigu en servant à la fois de fonction pour un traitement quelconque, mais aussi de constructeur de classe.
ECMAScript 2022 fait table rase de ce système pour devenir un véritable langage objet. Dans cet exemple, nous avons une classe Personne avec un constructeur (constructor) prenant en argument un nom et un prénom.
class Personne {
constructor( nom, prenom ) {
this.nom = nom;
this.prenom = prenom;
}
hello() {
alert( "Bonjour " + this.nom + " " + this.prenom );
}
}
La création d’une instance et son usage ne changent pas. On peut donc parfaitement avoir une librairie de classes propre à ECMAScript 2022 et une librairie compatible avec les anciens navigateurs sans changer le code principal.
let p = new Personne( "brillant", "alexandre" );
p.hello(); // Bonjour brillant alexandre
2. Attributs
Un des reproches des versions antérieures à la ES2022 concernait le fonctionnement des attributs qui n’étaient pas déclarés dans la classe mais uniquement à l’usage dans le corps des fonctions par le mot-clé this. Il est désormais possible d’indiquer les attributs de classe en leur affectant aussi une valeur initiale dans le corps de la classe.
Dans l’exemple ci-dessous, nous avons un nouvel attribut de classe roi.
class Personne {
roi = false;
constructor( nom, prenom ) {
this.nom = nom;
this.prenom = prenom;
}
hello() {
alert( ( this.roi ? "Sa majesté " : "Bonjour " ) + this.nom + " " + this.prenom );
}
}
function init() {
let p = new Personne( "pendragon", "arthur" );
p.roi = true; ...
Programmation modulaire simplifiée
1. Export
Pour construire un module, il vous suffit de créer un fichier script indépendant. Pour chaque classe ou fonction que vous souhaitez mettre à disposition, vous avez à préfixer la déclaration par le mot-clé export.
Dans cet exemple, nous avons mis à disposition d’un module vehicules.js une classe Vehicule avec en constructeur une marque et un modèle.
export class Vehicule {
constructor( marque, modele ) {
this.marque = marque;
this.modele = modele;
}
}
Il est également possible de définir la liste des classes et fonctions accessibles par la syntaxe : export { classe1, classe2..., fonction1... }.
L’exemple précédent aurait donc pu être écrit aussi de cette manière :
class Vehicule {
constructor( marque, modele ) {
this.marque = marque;
this.modele = modele;
}
}
export { Vehicule }
2. Import
Pour importer un module, nous utiliserons le mot-clé import. Il ne pourra être utilisé qu’à l’intérieur d’un autre module. Il existe deux manières pour importer les éléments d’un module. La première consiste à obtenir...
Fonctions simplifiées
1. Expressions lambda
Les expressions lambda vont simplifier l’écriture de fonctions.
Dans l’exemple ci-dessous, nous avons une fonction associée à la variable t déclarée de manière classique.
let t = function test(a,b) { return a+b;}
alert( t(1,2) ); // « 3 »
Ici, cette même fonction est déclarée dans une forme simplifiée. Les opérandes et le résultat de la fonction sont séparés par =>.
let t2 = (a,b) => ( a+b );
alert( t(2,2) ); // « 4 »
Autre exemple, pour parcourir un tableau grâce à la fonction forEach et construire rapidement un nouveau tableau avec les valeurs inverses :
let a = [1,2,3,4,5];
let b = [];
a.forEach( v => b += -v );
console.log( b ); // -1 -2 -3 -4 -5
2. Itérateurs
Les itérateurs sont des fonctions qui ont pour seul rôle de retourner une suite de valeurs. Elles évitent le passage par un tableau et peuvent être utilisées directement dans une boucle. Elles sont distinguées par un astérisque. L’instruction yield sert à retourner chaque valeur.
let range = function* (min,max) {
while ( min <= max ) {
yield min++;
}
}
L’itérateur précédent...
Développement asynchrone
1. Simple
Lors d’un traitement asynchrone, on associe un traitement à un événement particulier qui va arriver dans l’avenir. Par exemple, on peut effectuer un traitement après un certain laps de temps ou bien après le chargement d’une ressource. Habituellement, on passe une fonction déléguée qui sera déclenchée lorsque l’événement aura lieu.
Par exemple, si nous affichons un message après trois secondes, nous pourrions écrire :
setTimeout( function() { alert( "Bonjour" ); }, 3000 );
Si nous avons ensuite d’autres traitements asynchrones à faire, le code peut vite devenir complexe car nous ne savons plus très bien quelle méthode est invoquée à quel moment.
ECMAScript2022 uniformise l’écriture de traitements asynchrones grâce à la classe Promise. Cette classe aura en constructeur la fonction à invoquer lors de l’événement ou bien une fonction gérant l’impossibilité de traiter l’événement.
Nous aurions pu écrire le cas précédent de cette manière :
let p = new Promise( ( fait, erreur ) => (
setTimeout( () => fait(), 3000 ) ) );
p.then( () => alert( "Bonjour") );
L’avantage étant...
Faciliter l’usage international
1. Nombres
La classe Intl dispose de nombreuses traductions en fonction des pays et langues, à commencer par le formatage des nombres avec ou sans séparateurs et en prenant en compte le séparateur des décimaux. La méthode statique NumberFormat permet de formater les nombres pour une localisation définie par la norme IETF BCP 47. De manière simplifiée, nous aurons un code pour représenter la langue et un code pour représenter le pays.
let frNum = new Intl.NumberFormat( "fr-FR" ); // format français
let usNum = new Intl.NumberFormat( "en-US" ); // format américain
let nombre = 3141567.314;
alert( "format en français = " + frNum.format( nombre ) );
alert( "format en anglais/us = " + usNum.format( nombre ) );
NumberFormat sans argument utilise la localisation par défaut.
2. Monnaies
Pour formater une somme d’argent, nous utiliserons également NumberFormat mais avec un argument supplémentaire. Il s’agira d’un objet précisant qu’il s’agit d’une monnaie et nous indiquerons la monnaie par un code à trois lettres.
frNum = new Intl.NumberFormat( "fr-FR", { style : "currency",
currency : "EUR" } );
alert( "Billet de " + frNum.format( 20 ) ); // « Billet...