Guide JavaScript Partie 8: Présentation des fonctionnalités d'ES6

Aujourd'hui, dans la huitième partie de la traduction du manuel JavaScript, nous passerons en revue les fonctionnalités du langage qui y figurait après la sortie de la norme ES6. D'une manière ou d'une autre, nous avons rencontré plusieurs de ces opportunités plus tôt, quelque part en les approfondissant, quelque part en tenant pour acquis. Cette section du guide vise, avec la divulgation de certains sujets que nous n'avons pas abordés auparavant, à rationaliser les connaissances d'un développeur novice dans le domaine du JavaScript moderne.

Partie 1: premier programme, fonctionnalités linguistiques, normes
Partie 2: style de code et structure du programme
Partie 3: variables, types de données, expressions, objets
Partie 4: caractéristiques
Partie 5: tableaux et boucles
Partie 6: exceptions, points-virgules, littéraux génériques
Partie 7: mode strict, ce mot-clé, événements, modules, calculs mathématiques
Partie 8: Présentation des fonctionnalités d'ES6
Partie 9: Présentation des normes ES7, ES8 et ES9



À propos d'ES6


La norme ES6, qui serait plus correcte d'appeler ES2015 ou ECMAScript 2015 (ce sont ses noms officiels, bien que tout le monde l'appelle ES6), est apparue 4 ans après la publication de la norme précédente - ES5.1. Il a fallu une dizaine d'années pour développer tout ce qui entrait dans la norme ES5.1. De nos jours, tout ce qui figurait dans cette norme est devenu l'outil habituel du développeur JS. Il convient de noter que ES6 a apporté des modifications majeures à la langue (tout en conservant une compatibilité descendante avec ses versions précédentes). Afin d'apprécier l'ampleur de ces changements, on peut noter que la taille du document décrivant la norme ES5 est d'environ 250 pages, et la norme ES6 est décrite dans un document qui compte déjà environ 600 pages.

La liste des innovations les plus importantes de la norme ES2015 peut comprendre les éléments suivants:

  • Fonctions fléchées
  • Promesses
  • Générateurs
  • Mots let clés let et const
  • Cours
  • Modules
  • Support littéral de modèle
  • Prise en charge des paramètres de fonction par défaut
  • Opérateur de diffusion
  • Affectation destructrice
  • Amélioration des littéraux d'objets
  • for...of boucle
  • Prise en charge des structures de données Map and Set

Considérez ces possibilités.

Fonctions fléchées


Les fonctions fléchées ont changé l'apparence du code JavaScript. En termes d'apparence, leur utilisation rend les déclarations de fonctions plus courtes et plus faciles. Voici la déclaration d'une fonction régulière.

 const foo = function foo() { //... } 

Mais presque la même (mais pas complètement similaire à la précédente) fonction de flèche.

 const foo = () => { //... } 

Si le corps de la fonction flèche se compose d'une seule ligne, dont le résultat doit être renvoyé par cette fonction, alors il est écrit encore plus court.

 const foo = () => doSomething() 

Si la fonction flèche ne prend qu'un seul paramètre, vous pouvez l'écrire comme suit.

 const foo = param => doSomething(param) 

Il est à noter qu'avec l'avènement des fonctions flèches, les fonctions ordinaires n'ont plus disparu, elles peuvent encore être utilisées dans le code, elles fonctionnent de la même manière qu'auparavant.

Ce mot-clé figure dans les fonctions fléchées


Les fonctions fléchées n'ont pas leur propre valeur, elles l'héritent du contexte d'exécution.

Cela corrige le problème, pour lequel, lors de l'utilisation de fonctions régulières, il était nécessaire d'utiliser des constructions comme var that = this pour préserver le contexte. Cependant, comme cela a été montré dans les parties précédentes du manuel, cette modification affecte sérieusement les caractéristiques de l'utilisation des fonctions fléchées et la portée de leur application.

Promesses


Les promesses vous permettent de vous débarrasser du problème bien connu appelé «enfer de rappel», bien que leur utilisation implique l'utilisation de structures assez complexes. Ce problème a été résolu dans la norme ES2017 avec l'avènement de la construction async/await , qui est basée sur des promesses.

Les développeurs JavaScript ont utilisé des promesses avant la norme ES2015, en utilisant diverses bibliothèques pour cela (par exemple - jQuery, q, deferred.js, vow). Cela indique l'importance et la pertinence de ce mécanisme. Différentes bibliothèques l'implémentent de différentes manières, l'émergence d'une norme dans ce domaine peut être considérée comme un fait très positif.
Voici le code écrit à l'aide des fonctions de rappel (rappels).

 setTimeout(function() { console.log('I promised to run after 1s') setTimeout(function() {   console.log('I promised to run after 2s') }, 1000) }, 1000) 

En utilisant des promesses, cela peut être réécrit comme suit.

 const wait = () => new Promise((resolve, reject) => { setTimeout(resolve, 1000) }) wait().then(() => { console.log('I promised to run after 1s') return wait() }) .then(() => console.log('I promised to run after 2s')) 

Générateurs


Les générateurs sont des fonctions spéciales qui peuvent suspendre leur propre exécution et la reprendre. Cela permet à un autre code d'être exécuté pendant que le générateur est inactif.

Le générateur décide lui-même qu'il doit faire une pause et permettre à un autre code, "en attente" de son tour, de s'exécuter. Dans le même temps, le générateur a la possibilité de poursuivre son exécution après que l'opération, dont il attend les résultats, soit terminée.

Tout cela se fait grâce à un seul mot-clé simple de yield . Lorsque ce mot-clé est trouvé dans le générateur, son exécution est suspendue.
Un générateur peut contenir plusieurs lignes avec ce mot-clé, interrompant sa propre exécution plusieurs fois. Les générateurs sont déclarés à l'aide de la construction de *function . Cet astérisque devant le mot function ne doit pas être pris pour quelque chose comme un opérateur de déréférencement de pointeur utilisé dans des langages comme C, C ++ ou Go.

Les générateurs marquent l'avènement d'un nouveau paradigme de programmation JavaScript. En particulier, ils permettent l'échange de données bidirectionnel entre le générateur et un autre code, et permettent la création de boucles de longue durée de vie qui ne «suspendent» pas le programme.

Prenons un exemple illustrant les caractéristiques du fonctionnement des générateurs. Voici le générateur lui-même.

 function *calculator(input) {   var doubleThat = 2 * (yield (input / 2))   var another = yield (doubleThat)   return (input * doubleThat * another) } 

Avec cette commande, nous l'initialisons.

 const calc = calculator(10) 

Puis nous nous tournons vers son itérateur.

 calc.next() 

Cette commande démarre un itérateur, elle retourne un tel objet.

 { done: false value: 5 } 

Ici, ce qui suit se produit. Le code exécute une fonction en utilisant la valeur d' input transmise au constructeur du générateur. Le code générateur est exécuté jusqu'à ce que le mot-clé yield soit trouvé. À ce stade, il renvoie le résultat de la division de l' input par 2 , ce qui, puisque l' input est 10 , donne le nombre 5 . Nous obtenons ce nombre grâce à l'itérateur et, avec lui, une indication que le générateur n'est pas encore terminé (la propriété done dans l'objet retourné par l'itérateur est définie sur false ), c'est-à-dire que la fonction n'a été suspendue.
La prochaine fois que l'itérateur sera appelé, nous passerons le numéro 7 au générateur.

 calc.next(7) 

En réponse à cela, l'itérateur nous renvoie l'objet suivant.

 { done: false value: 14 } 

Ici, le nombre 7 été utilisé pour calculer la valeur doubleThat .

À première vue, il peut sembler que le code d' input / 2 ressemble à un argument d'une fonction, mais ce n'est que la valeur renvoyée à la première itération. Ici, nous sautons cette valeur et utilisons la nouvelle valeur d'entrée 7 , en la multipliant par 2 . Après cela, nous arrivons au deuxième mot clé yield , par conséquent, la valeur obtenue dans la deuxième itération est 14 .

À la prochaine itération, qui est la dernière, nous passons le nombre 100 au générateur.

 calc.next(100) 

En réponse, nous obtenons l'objet suivant.

 { done: true value: 14000 } 

L'itération est terminée (le mot-clé yield ne se trouve plus dans le générateur), le résultat de l'évaluation de l'expression (input * doubleThat * another) retourné dans l'objet, soit - 10 * 14 * 100 et une indication de l'achèvement de l'itérateur ( done: true ).

Mots-clés let et const


JavaScript a toujours utilisé le mot clé var pour déclarer des variables. Ces variables ont une portée fonctionnelle. Les mots clés let et const , respectivement, vous permettent de déclarer des variables et des constantes qui ont une portée de bloc.

Cela signifie que, par exemple, une variable déclarée à l'aide du mot clé let dans une boucle, à l'intérieur d'un bloc if , ou à l'intérieur d'un bloc de code normal limité par des accolades, n'ira pas au-delà de ce bloc. Les variables déclarées avec var ne sont pas conservées dans de tels blocs, devenant disponibles dans la fonction au niveau de laquelle elles sont déclarées.

Le mot clé const fonctionne exactement comme let , mais avec lui, les constantes immuables sont déclarées.

Dans le code JS moderne, le mot-clé var est rarement utilisé. Il a cédé la place aux mots clés let et const . Dans le même temps, ce qui peut sembler inhabituel, le mot-clé const est très largement utilisé aujourd'hui, ce qui indique la popularité des idées d'immunité des entités dans la programmation moderne.

Cours


Il s'est avéré que JavaScript était le seul langage extrêmement répandu utilisant le modèle d'héritage prototype. Les programmeurs passant à JS à partir de langages qui implémentent le mécanisme d'héritage basé sur les classes se sentaient mal à l'aise dans un tel environnement. La norme ES2015 a introduit la prise en charge des classes en JavaScript. Il s'agit essentiellement de «sucre syntaxique» autour des mécanismes internes de JS utilisant des prototypes. Cependant, cela affecte la façon exacte dont les applications JS écrivent.

Les mécanismes d'héritage JavaScript ressemblent désormais à des mécanismes similaires dans d'autres langages orientés objet.

 class Person { constructor(name) {   this.name = name } hello() {   return 'Hello, I am ' + this.name + '.' } } class Actor extends Person { hello() {   return super.hello() + ' I am an actor.' } } var tomCruise = new Actor('Tom Cruise') console.log(tomCruise.hello()) 

Ce programme affiche le texte Hello, I am Tom Cruise. I am an actor sur la console Hello, I am Tom Cruise. I am an actor Hello, I am Tom Cruise. I am an actor .
Dans les classes JS, les variables d'instance ne peuvent pas être déclarées; elles doivent être initialisées dans les constructeurs.

Constructeur de classe


Les classes ont une méthode spéciale, constructor , qui est appelée lorsqu'une instance de la classe est créée à l'aide du new mot clé.

▍ Mot-clé super


Le super mot super clé vous permet d'accéder à la classe parent à partir des classes descendantes.

▍ Getters et setters


Le getter d'une propriété peut être défini comme suit.

 class Person { get fullName() {   return `${this.firstName} ${this.lastName}` } } 

Le passeur peut être décrit comme indiqué ci-dessous.

 class Person { set age(years) {   this.theAge = years } } 

Ils travaillent avec des getters et des setters comme s'ils n'étaient pas des fonctions, mais des propriétés ordinaires des objets.

Modules


Avant la norme ES2015, il y avait plusieurs approches concurrentes pour travailler avec des modules. En particulier, nous parlons des technologies RequireJS et CommonJS. Cette situation a conduit à un désaccord dans la communauté des développeurs JS.

De nos jours, grâce à la standardisation des modules dans ES2015, la situation se normalise progressivement.

▍ Importer des modules


Les modules sont importés à l'aide d'une construction du formulaire import...from... Voici quelques exemples.

 import * as something from 'mymodule' import React from 'react' import { React, Component } from 'react' import React as MyLibrary from 'react' 

▍ Exportation de modules


Les mécanismes internes du module sont fermés du monde extérieur, mais à partir du module, vous pouvez exporter tout ce qu'il peut offrir à d'autres modules. Cela se fait à l'aide du mot-clé d' export .

 export var foo = 2 export function bar() { /* ... */ } 

▍ Littéraux de modèle


Les littéraux de modèle sont une nouvelle façon de décrire les chaînes en JavaScript. Voici à quoi ça ressemble.

 const aString = `A string` 

De plus, l'utilisation de la syntaxe des littéraux de modèle vous permet d'incorporer des expressions dans des chaînes et de les interpoler. Cela se fait en utilisant une construction de la forme ${a_variable} . Voici un exemple simple de son utilisation:

 const v = 'test' const str = `something ${v}` //something test 

Voici un exemple plus compliqué, illustrant la possibilité d'évaluer des expressions et de substituer leurs résultats dans une chaîne.

 const str = `something ${1 + 2 + 3}` const str2 = `something ${foo() ? 'x' : 'y' }` 

Grâce à l'utilisation de littéraux de modèle, il est devenu beaucoup plus facile de déclarer des chaînes multi-lignes.

 const str3 = `Hey this string is awesome!` 

Comparez cela avec ce que vous avez dû faire pour décrire les chaînes multilignes lors de l'utilisation des fonctionnalités disponibles dans la langue avant ES2015.

 var str = 'One\n' + 'Two\n' + 'Three' 

Paramètres de fonction par défaut


Désormais, les fonctions prennent en charge les paramètres utilisés par défaut - dans le cas où les arguments correspondants ne leur sont pas transmis lors de l'appel des fonctions.

 const foo = function(index = 0, testing = true) { /* ... */ } foo() 

Opérateur de diffusion


L'opérateur d'étalement (opérateur d'extension) vous permet de «développer» des tableaux, des objets ou des chaînes. Cet opérateur ressemble à trois points ( ... ). Tout d'abord, considérez-le avec un exemple de tableau.

 const a = [1, 2, 3] 

Voici comment créer un nouveau tableau basé sur ce tableau.

 const b = [...a, 4, 5, 6] 

Voici comment créer une copie du tableau.

 const c = [...a] 

Cet opérateur fonctionne également avec les objets. Par exemple, voici comment l'utiliser pour cloner un objet.

 const newObj = { ...oldObj } 

En appliquant l'opérateur d'étalement à une chaîne, vous pouvez le convertir en un tableau, dont chaque élément contient un caractère de cette chaîne.

 const hey = 'hey' const arrayized = [...hey] // ['h', 'e', 'y'] 

Cet opérateur, en plus des variantes ci-dessus de son application, est pratique à utiliser lors de l'appel de fonctions qui attendent une liste normale d'arguments, en leur passant un tableau avec ces arguments.

 const f = (foo, bar) => {} const a = [1, 2] f(...a) 

Auparavant, cela se faisait à l'aide d'une construction de la forme f.apply(null, a) , mais un tel code est plus difficile à écrire et il est moins lisible.

Affectation destructrice


La technique d'assignation déstructurante permet, par exemple, de prendre un objet, d'en extraire certaines valeurs et de les placer dans des variables ou constantes nommées.

 const person = { firstName: 'Tom', lastName: 'Cruise', actor: true, age: 54, } const {firstName: name, age} = person 

Ici, les propriétés firstName et age sont récupérées de l'objet. La propriété age est écrite dans la constante déclarée avec le même nom et la propriété firstName , après extraction, tombe dans le name constant.

L'affectation destructive convient également pour travailler avec des tableaux.

 const a = [1,2,3,4,5] const [first, second, , , fifth] = a 

Les first , second et fifth constantes obtiennent respectivement les premier, deuxième et cinquième éléments du tableau.

Amélioration des littéraux d'objets


ES2015 a considérablement étendu la capacité de décrire des objets à l'aide de littéraux d'objets.

▍ Simplification de l'inclusion de variables dans les objets


Auparavant, pour affecter une variable à une propriété d'un objet, il était nécessaire d'utiliser la construction suivante.

 const something = 'y' const x = { something: something } 

Maintenant, la même chose peut être faite comme ça.

 const something = 'y' const x = { something } 

▍ Prototypes


Le prototype de l'objet peut maintenant être défini en utilisant la construction suivante.

 const anObject = { y: 'y' } const x = { __proto__: anObject } 

▍ Mot-clé super


En utilisant le super mot super clé, les objets peuvent accéder aux objets prototypes. Par exemple, pour appeler leurs méthodes qui portent le même nom que les méthodes de ces objets eux-mêmes.

 const anObject = { y: 'y', test: () => 'zoo' } const x = { __proto__: anObject, test() {   return super.test() + 'x' } } x.test() //zoox 

▍ Noms de propriété calculés


Les noms de propriété calculés sont formés au stade de la création d'objet.

 const x = { ['a' + '_' + 'b']: 'z' } x.a_b //z 

Pour ... de boucle


En 2009, dans la norme ES5, des boucles forEach() sont apparues. Il s'agit d'une conception utile, dont l'inconvénient est le fait que de tels cycles sont très difficiles à interrompre. Le classique for boucle dans les situations où vous devez interrompre l'exécution de la boucle avant son achèvement normal est un choix beaucoup plus approprié.

Un for...of cycle est apparu dans ES2015, qui, d'une part, se distingue par sa syntaxe concise et la commodité de forEach , et d'autre part, il prend en charge la possibilité d'une sortie anticipée du cycle.

Voici quelques exemples for...of exemples for...of boucles.

 //    for (const v of ['a', 'b', 'c']) { console.log(v); } //           entries() for (const [i, v] of ['a', 'b', 'c'].entries()) { console.log(i, v); } 

Mapper et définir des structures de données


ES2015 a introduit les structures de données Map and Set (ainsi que leurs versions «faibles» WeakMap et WeakSet , dont l'utilisation améliore les performances du «garbage collector» - le mécanisme responsable de la gestion de la mémoire dans les moteurs JS). Ce sont des structures de données très populaires qui, avant l'apparition de leur implémentation officielle, devaient être imitées à l'aide des outils linguistiques disponibles.

Résumé


Aujourd'hui, nous avons passé en revue les caractéristiques de la norme ES2015, qui ont grandement influencé l'état actuel de la langue. Notre prochain sujet sera consacré aux fonctionnalités des normes ES2016, ES2017 et ES2018.

Chers lecteurs! Quelles innovations de la norme ES6 trouvez-vous les plus utiles?

Source: https://habr.com/ru/post/fr431074/


All Articles