Aller au contenu principal

ES2015, ES2016, et au-delà

· 10 minutes de lecture
l'équipe V8, Les passionnés d'ECMAScript

L'équipe V8 accorde une grande importance à l'évolution de JavaScript vers un langage de plus en plus expressif et bien défini qui facilite l'écriture d'applications web rapides, sûres et correctes. En juin 2015, la spécification ES2015 a été ratifiée par le comité de normalisation TC39, faisant d'elle la plus grande mise à jour unique du langage JavaScript. Les nouvelles fonctionnalités incluent les classes, les fonctions fléchées, les promesses, les itérateurs / générateurs, les proxies, les symboles bien connus, et un sucre syntaxique supplémentaire. TC39 a également accéléré le rythme des nouvelles spécifications et a publié en février 2016 le projet de candidat pour ES2016 qui doit être ratifié cet été. Bien qu'il ne soit pas aussi vaste que la mise à jour ES2015 en raison du cycle de publication plus court, ES2016 introduit notamment l'opérateur d'exponentiation et Array.prototype.includes.

Aujourd'hui, nous avons atteint une étape importante : V8 prend en charge ES2015 et ES2016. Vous pouvez utiliser les nouvelles fonctionnalités du langage dès aujourd'hui dans Chrome Canary, et elles seront activées par défaut dans Chrome 52.

Étant donné la nature d'une spécification évolutive, les différences entre divers types de tests de conformité et la complexité du maintien de la compatibilité web, il peut être difficile de déterminer quand une version spécifique d'ECMAScript est considérée comme entièrement prise en charge par un moteur JavaScript. Continuez à lire pour savoir pourquoi la prise en charge des spécifications est plus nuancée que des numéros de version, pourquoi les appels de queue propres sont encore en discussion et quels autres points d'attention restent en jeu.

Une spécification évolutive

Lorsque TC39 a décidé de publier des mises à jour plus fréquentes de la spécification JavaScript, la version la plus à jour du langage est devenue la principale version en projet. Bien que des versions de la spécification ECMAScript soient encore produites et ratifiées chaque année, V8 implémente une combinaison de la version la plus récemment ratifiée (par exemple, ES2015), de certaines fonctionnalités qui sont suffisamment proches de la standardisation pour être sûres à implémenter (par exemple, l'opérateur d'exponentiation et Array.prototype.includes() du projet de candidat ES2016), et une collection de corrections de bugs et d'amendements de compatibilité web des projets plus récents. Une partie de la logique derrière cette approche est que les implémentations de langage dans les navigateurs devraient correspondre à la spécification, même si c'est la spécification qui doit être mise à jour. En fait, le processus d'implémentation d'une version ratifiée de la spécification découvre souvent de nombreuses corrections et clarifications qui constituent la version suivante de la spécification.

Parties actuellement livrées de la spécification évolutive ECMAScript

Par exemple, lors de l'implémentation du drapeau sticky des expressions rationnelles ES2015, l'équipe V8 a découvert que les sémantiques de la spécification ES2015 cassaient de nombreux sites existants (y compris tous les sites utilisant les versions 2.x.x de la populaire bibliothèque XRegExp). Puisque la compatibilité est une pierre angulaire du web, les ingénieurs des équipes V8 et Safari JavaScriptCore ont proposé un amendement à la spécification des expressions rationnelles pour corriger le problème, qui a été accepté par TC39. L'amendement n'apparaîtra pas dans une version ratifiée avant ES2017, mais il fait toujours partie du langage ECMAScript et nous l'avons implémenté pour livrer le drapeau sticky des expressions rationnelles.

Le raffinement continu de la spécification du langage et le fait que chaque version (y compris le projet qui n'a pas encore été ratifié) remplace, modifie et clarifie les versions précédentes rendent difficile de comprendre les complexités derrière la prise en charge ES2015 et ES2016. Bien qu'il soit impossible d'exprimer cela de manière succincte, il est peut-être plus exact de dire que V8 prend en charge la conformité avec « le projet d'avenir continuellement maintenu de la norme ECMAScript » !

Mesurer la conformité

Dans une tentative de comprendre cette complexité des spécifications, il existe une variété de façons de mesurer la compatibilité des moteurs JavaScript avec la norme ECMAScript. L'équipe V8, ainsi que d'autres fournisseurs de navigateurs, utilisent la suite de tests Test262 comme référence ultime de conformité à l'ébauche de la norme ECMAScript future constamment mise à jour. Cette suite de tests est continuellement mise à jour pour correspondre à la spécification et fournit 16 000 tests fonctionnels discrets pour toutes les fonctionnalités et cas limites qui constituent une implémentation de JavaScript compatible et conforme. Actuellement, V8 réussit environ 98% des tests de la suite Test262, et les 2% restants sont une poignée de cas limites et de fonctionnalités ES futures pas encore prêtes à être déployées.

Étant donné qu'il est difficile de parcourir les nombreux tests de Test262, d'autres tests de conformité existent, tels que la table de compatibilité Kangax. Kangax facilite le survol pour voir si une fonctionnalité particulière (comme les fonctions fléchées) a été implémentée dans un moteur donné, mais ne teste pas tous les cas limites de conformité que Test262 fait. Actuellement, Chrome Canary obtient un score de 98% sur la table Kangax pour ES2015 et 100% sur les sections de Kangax correspondant à ES2016 (par exemple les sections intitulées '2016 features' et '2016 misc' sous l'onglet ESnext).

Les 2% restants des tests de la table Kangax pour ES2015 concernent les appels en queue propre, une fonctionnalité qui a été implémentée dans V8, mais volontairement désactivée dans Chrome Canary en raison de préoccupations concernant l'expérience des développeurs détaillées ci-dessous. Avec l'activation de l'option « Fonctionnalités JavaScript expérimentales », qui force cette fonctionnalité, Canary obtient un score de 100% sur l'ensemble de la table Kangax pour ES2015.

Appels en queue propre

Les appels en queue propre ont été implémentés mais n'ont pas encore été déployés étant donné qu'une modification de cette fonctionnalité est actuellement en discussion au sein de TC39. ES2015 spécifie que les appels de fonction en mode strict en position de queue ne doivent jamais provoquer de débordement de pile. Bien que ce soit une garantie utile pour certains modèles de programmation, les sémantiques actuelles posent deux problèmes. Premièrement, puisque l'élimination des appels en queue est implicite, il peut être difficile pour les programmeurs d'identifier quelles fonctions se trouvent réellement en position de queue. Cela signifie que les développeurs peuvent ne pas découvrir les tentatives mal placées d'appels en queue dans leurs programmes jusqu'à ce que la pile déborde. Deuxièmement, la mise en œuvre des appels en queue propre nécessite l'élimination des cadres de pile d'appel en queue de la pile, ce qui fait perdre des informations sur le flux d'exécution. Cela a deux conséquences :

  1. Cela rend plus difficile de comprendre lors du débogage comment l'exécution est arrivée à un certain point, car la pile contient des discontinuités, et
  2. error.stack contient moins d'informations sur le flux d'exécution, ce qui peut perturber les logiciels de télémétrie qui collectent et analysent les erreurs côté client.

La mise en œuvre d'une pile de substitution peut améliorer la lisibilité des piles d'appels, mais les équipes V8 et DevTools estiment que le débogage est plus facile, plus fiable et plus précis lorsque la pile affichée pendant le débogage est complètement déterministe et correspond toujours à l'état réel de la pile de machine virtuelle. En outre, une pile de substitution est trop coûteuse en termes de performances pour être activée en permanence.

Pour ces raisons, l'équipe V8 soutient fortement la dénotation des appels en queue propre par une syntaxe spéciale. Il existe une proposition TC39 en attente appelée appels en queue syntaxique pour spécifier ce comportement, co-soutenue par des membres du comité de Mozilla et Microsoft. Nous avons implémenté et mis en scène les appels en queue propre tels que spécifiés dans ES2015 et commencé à mettre en œuvre les appels en queue syntaxique tels que spécifiés dans la nouvelle proposition. L'équipe V8 prévoit de résoudre le problème lors de la prochaine réunion TC39 avant de déployer par défaut les appels en queue implicite propre ou syntaxique. Vous pouvez tester chaque version en attendant en utilisant les options V8 --harmony-tailcalls et --harmony-explicit-tailcalls. Mise à jour : ces options ont été supprimées.

Modules

L'une des promesses les plus passionnantes d'ES2015 est la prise en charge des modules JavaScript pour organiser et séparer différentes parties d'une application en espaces de noms. ES2015 spécifie les déclarations import et export pour les modules, mais pas comment les modules sont chargés dans un programme JavaScript. Dans le navigateur, le comportement de chargement a récemment été spécifié via <script type="module">. Bien qu'un travail supplémentaire de standardisation soit nécessaire pour spécifier des API avancées de chargement dynamique de modules, la prise en charge des balises de scripts de module dans Chromium est déjà en développement. Vous pouvez suivre le travail d'implémentation sur le bug de lancement et lire plus sur les idées d'API de chargeur expérimentales dans le dépôt whatwg/loader.

ESnext et au-delà

À l'avenir, les développeurs peuvent s'attendre à ce que les mises à jour d'ECMAScript soient plus petites, plus fréquentes et avec des cycles de mise en œuvre plus courts. L'équipe V8 travaille déjà pour intégrer des fonctionnalités à venir telles que les mots-clés async/await, Object.values / Object.entries, String.prototype.{padStart,padEnd} et RegExp lookbehind dans le runtime. Revenez nous voir pour plus de mises à jour sur les progrès de notre implémentation ESnext et les optimisations de performance pour les fonctionnalités existantes d'ES2015 et ES2016+.

Nous nous efforçons de continuer à faire évoluer JavaScript et de trouver le juste équilibre entre l'implémentation précoce de nouvelles fonctionnalités, la garantie de la compatibilité et de la stabilité du web existant, et le retour d'expérience à TC39 concernant les préoccupations liées à la conception. Nous sommes impatients de voir les expériences incroyables que les développeurs créeront avec ces nouvelles fonctionnalités.