Aujourd'hui, dans la neuvième partie de la traduction du manuel JavaScript, un aperçu sera donné des fonctionnalités apparues dans le langage grâce aux normes ES7, ES8 et ES9.
→
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
Norme ES7
La norme ES7, qui, selon la terminologie officielle, s'appelle ES2016, a été publiée à l'été 2016. Lui, par rapport à ES6, apporté à la langue n'est pas très nouveau. En particulier, nous parlons de ce qui suit:
Array.prototype.includes()
méthode.- Opérateur d'exponentiation.
▍ Méthode Array.prototype.includes ()
La méthode
Array.prototype.includes()
est conçue pour vérifier la présence d'un élément dans le tableau. Trouver le désiré dans le tableau, il retourne
true
, ne trouvant pas -
false
. Avant ES7, la méthode
indexOf()
était utilisée pour effectuer la même opération, qui retourne, si un élément est trouvé, le premier index par lequel il peut être trouvé dans le tableau. Si
indexOf()
ne trouve pas l'élément, il renvoie le nombre
-1
.
Selon les règles de conversion de type JavaScript, le nombre
-1
converti en
true
. Par conséquent, pour vérifier les résultats de l'opération d'
indexOf()
il faut utiliser une construction pas particulièrement pratique de la forme suivante.
if ([1,2].indexOf(3) === -1) { console.log('Not found') }
Si dans une situation similaire, en supposant que
indexOf()
, sans trouver d'élément, renvoie
false
, utilisez quelque chose comme celui illustré ci-dessous, le code ne fonctionnera pas correctement.
if (![1,2].indexOf(3)) {
Dans ce cas, il s'avère que la construction
![1,2].indexOf(3)
donne
false
.
En utilisant la méthode
includes()
, ces comparaisons semblent beaucoup plus logiques.
if (![1,2].includes(3)) { console.log('Not found') }
Dans ce cas, la construction
[1,2].includes(3)
renvoie
false
, cette valeur est un opérateur
!
devient
true
et la console reçoit un message indiquant que l'élément dans le tableau est introuvable.
▍ opérateur d'exponentiation
L'opérateur d'exponentiation remplit la même fonction que la méthode
Math.pow()
, mais il est plus pratique de l'utiliser qu'une fonction de bibliothèque, car elle fait partie du langage.
Math.pow(4, 2) == 4 ** 2
Cet opérateur peut être considéré comme un ajout agréable à JS, qui est utile dans les applications qui effectuent certains calculs. Un opérateur similaire existe dans d'autres langages de programmation.
Norme ES8
La norme ES8 (ES2017) a été publiée en 2017. Comme ES7, il n'a pas apporté grand-chose à la langue. À savoir, nous parlons des fonctionnalités suivantes:
- Ajout de chaînes à une longueur donnée.
- Méthode
Object.values()
. - Méthode
Object.entries()
. - Méthode
Object.getOwnPropertyDescriptors()
. - Virgules de fin dans les paramètres de fonction.
- Fonctions asynchrones.
- Travaillez avec la mémoire partagée et les opérations atomiques.
▍Ajout de lignes à une longueur donnée
ES8 a introduit deux nouvelles méthodes d'objet
String
-
padStart()
et
padEnd()
.
La méthode
padStart()
remplit la ligne actuelle avec une autre ligne jusqu'à ce que la ligne finale atteigne la longueur souhaitée. Le remplissage a lieu au début de la ligne (à gauche). Voici comment utiliser cette méthode.
str.padStart(targetLength [, padString])
Ici
str
est la ligne actuelle,
targetLength
est la longueur de la ligne finale (si elle est inférieure à la longueur de la ligne actuelle, cette ligne sera renvoyée sans modifications),
padString
est un paramètre facultatif - la ligne utilisée pour remplir la ligne actuelle. Si
padString
pas spécifié, un caractère espace est utilisé pour
padString
ligne actuelle à la longueur spécifiée.
La méthode
padEnd()
est similaire à
padStart()
, mais la ligne est remplie à droite.
Considérez des exemples d'utilisation de ces méthodes.
const str = 'test'.padStart(10) const str1 = 'test'.padEnd(10,'*') console.log(`'${str}'`)
Ici, lorsque vous utilisez
padStart()
avec uniquement la longueur souhaitée de la chaîne résultante, des espaces ont été ajoutés au début de la chaîne d'origine. Lorsque vous utilisez
padEnd()
avec la longueur de la ligne finale et la ligne pour la remplir, les caractères
*
ont été ajoutés à la fin de la ligne d'origine.
▍ Méthode Object.values ()
Cette méthode renvoie un tableau contenant les valeurs des propriétés de l'objet, c'est-à-dire les propriétés que l'objet lui-même contient, et non celles qui lui sont accessibles via la chaîne de prototype.
Voici comment l'utiliser.
const person = { name: 'Fred', age: 87 } const personValues = Object.values(person) console.log(personValues)
Cette méthode s'applique également aux tableaux.
▍ Méthode Object.entries ()
Cette méthode renvoie un tableau, dont chaque élément est également un tableau contenant, au format
[key, value]
, les clés et les valeurs des propres propriétés de l’objet.
const person = { name: 'Fred', age: 87 } const personValues = Object.entries(person) console.log(personValues)
Lors de l'application de cette méthode aux tableaux, les indices des éléments sont affichés sous forme de clés et ce qui est stocké dans le tableau aux indices correspondants est affiché sous forme de valeurs.
▍ méthode getOwnPropertyDescriptors ()
Cette méthode renvoie des informations sur toutes les propriétés de l'objet. Les ensembles d'attributs (descripteurs) sont associés aux propriétés des objets. En particulier, nous parlons des attributs suivants:
value
- la valeur de la propriété de l'objet.writable
- contient true
si la propriété peut être modifiée.get
- contient une fonction getter associée à la propriété ou, en l'absence d'une telle fonction, undefined
.set
- contient la fonction de set
de la propriété ou undefined
.configurable
- si elle est false
- la propriété ne peut pas être supprimée, ses attributs ne peuvent pas être modifiés à l'exception de la valeur.enumerable
- si true est contenu dans cette propriété - la
est énumérable.
Voici comment utiliser cette méthode.
Object.getOwnPropertyDescriptors(obj)
Il prend un objet dont vous devez connaître les informations de propriété et renvoie un objet contenant ces informations.
const person = { name: 'Fred', age: 87 } const propDescr = Object.getOwnPropertyDescriptors(person) console.log(propDescr)
Pourquoi cette méthode est-elle nécessaire? Le fait est qu'il vous permet de créer de petites copies d'objets, en copiant, en plus d'autres propriétés, des getters et des setters. Cela ne pouvait pas être fait en utilisant la méthode
Object.assign()
, qui apparaissait dans la norme ES6, pour copier des objets.
L'exemple suivant a un objet avec un setter qui affiche, à l'aide de
console.log()
, ce qu'ils essaient d'écrire dans sa propriété correspondante.
const person1 = { set name(newName) { console.log(newName) } } person1.name = 'x'
Essayons de copier cet objet en utilisant la méthode
assign()
.
const person2 = {} Object.assign(person2, person1) person2.name = 'x'
Comme vous pouvez le voir, cette approche ne fonctionne pas. La propriété
name
, qui était le setter dans l'objet d'origine, est maintenant représentée comme une propriété régulière.
Nous allons maintenant copier l'objet en utilisant les méthodes
Object.defineProperties()
(il est apparu dans ES5.1) et
Object.getOwnPropertyDescriptors()
.
const person3 = {} Object.defineProperties(person3, Object.getOwnPropertyDescriptors(person1)) person3.name = 'x'
Ici, le setter reste dans la copie de l'objet.
Il convient de noter que les restrictions spécifiques à
Object.assign()
sont également caractéristiques de la méthode
Object.create()
lorsqu'elle est utilisée pour cloner des objets.
▍ Virgules de complétion dans les paramètres de fonction
Cette fonctionnalité vous permet de laisser une virgule à la fin de la liste des paramètres ou arguments, respectivement, lors de la déclaration et lors de l'appel de fonctions.
const doSomething = ( var1, var2, ) => {
Cela améliore la convivialité des systèmes de contrôle de version. A savoir, nous parlons du fait que lors de l'ajout de nouveaux paramètres à une fonction, vous n'avez pas à modifier le code existant juste pour le plaisir d'insérer une virgule.
▍ Fonctions asynchrones
La construction
async/await
est apparue dans la norme ES2017, qui peut être considérée comme l'innovation la plus importante de cette version du langage.
Les fonctions asynchrones sont une combinaison de promesses et de générateurs; elles simplifient les constructions qui nécessitaient auparavant une grande quantité de code modèle et des chaînes de promesses peu pratiques à décrire. En fait, nous parlons d'une abstraction de haut niveau sur les promesses.
Lorsque des promesses sont apparues dans la norme ES2015, elles ont été conçues pour résoudre les problèmes existants avec le code asynchrone, ce qu'elles ont fait. Mais au cours des deux années qui ont partagé les normes ES2015 et ES2017, il est devenu clair que les promesses ne peuvent pas être considérées comme la solution finale à ces problèmes.
En particulier, les promesses visaient à résoudre le problème de «l'enfer de rappel», mais, ayant résolu ce problème, elles-mêmes n'ont pas montré leur meilleur côté en raison de la complexité du code dans lequel elles sont utilisées. En fait, la construction
async/await
résout le problème des promesses et améliore l'utilisabilité du code asynchrone.
Prenons un exemple.
function doSomethingAsync() { return new Promise((resolve) => { setTimeout(() => resolve('I did something'), 3000) }) } async function doSomething() { console.log(await doSomethingAsync()) } console.log('Before') doSomething() console.log('After')
Ce code affichera les éléments suivants sur la console.
Before After I did something
Comme vous pouvez le voir, après avoir appelé
doSomething()
programme continue de s'exécuter, après
Before
,
After
s'affiche dans la console, et après trois secondes,
I did something
.
Appel de fonction asynchrone série
Si nécessaire, les fonctions asynchrones peuvent former quelque chose comme des chaînes d'appels. De tels designs se distinguent par une meilleure lisibilité que quelque chose de similaire, basé uniquement sur des promesses. Cela peut être vu dans l'exemple suivant.
function promiseToDoSomething() { return new Promise((resolve)=>{ setTimeout(() => resolve('I did something'), 10000) }) } async function watchOverSomeoneDoingSomething() { const something = await promiseToDoSomething() return something + ' and I watched' } async function watchOverSomeoneWatchingSomeoneDoingSomething() { const something = await watchOverSomeoneDoingSomething() return something + ' and I watched as well' } watchOverSomeoneWatchingSomeoneDoingSomething().then((res) => { console.log(res)
▍ Mémoire partagée et opérations atomiques
Nous parlons ici de l'objet
SharedArrayBuffer , qui vous permet de décrire les zones de mémoire partagée, et de l'objet
Atomics , qui contient un ensemble d'opérations atomiques sous la forme de méthodes statiques. Des détails sur les possibilités que ces objets offrent au programmeur peuvent être trouvés
ici .
Norme ES9
ES9 (ES2018) est la dernière version de la norme au moment de la publication de ce document. Voici ses principales caractéristiques:
- Appliquez des instructions d'étalement et de repos aux objets.
- Itérateurs asynchrones.
- Méthode
Promise.prototype.finally()
. - Améliorations des expressions régulières.
▍Application des opérateurs d'étalement et de repos aux objets
Nous avons déjà parlé des opérateurs de repos et de propagation qui sont apparus dans ES6 et peuvent être utilisés pour travailler avec des tableaux. Les deux ressemblent à trois points. L'opérateur reste, dans l'exemple suivant de déstructuration d'un tableau, vous permet de placer ses premier et deuxième éléments dans les constantes
first
et
second
, et tout le reste dans les
others
constants.
const numbers = [1, 2, 3, 4, 5] const [first, second, ...others] = numbers console.log(first)
L'opérateur d'
spread
vous permet de passer des tableaux à des fonctions qui attendent des listes de paramètres régulières.
const numbers = [1, 2, 3, 4, 5] const sum = (a, b, c, d, e) => a + b + c + d + e const res = sum(...numbers) console.log(res)
Maintenant, en utilisant la même approche, vous pouvez travailler avec des objets. Voici un exemple d'utilisation de l'instruction rest dans une opération d'affectation destructrice.
const { first, second, ...others } = { first: 1, second: 2, third: 3, fourth: 4, fifth: 5 } console.log(first)
Voici l'instruction spread utilisée lors de la création d'un nouvel objet basé sur un objet existant. Cet exemple continue le précédent.
const items = { first, second, ...others } console.log(items)
▍ Itérateurs asynchrones
La nouvelle construction
for-await-of
vous permet d'appeler des fonctions asynchrones qui renvoient des promesses en boucles. Ces boucles attendent la résolution de la promesse avant de passer à l'étape suivante. Voici à quoi ça ressemble.
for await (const line of readLines(filePath)) { console.log(line) }
Dans le même temps, il convient de noter que ces boucles doivent être utilisées dans les fonctions asynchrones - de la même manière que lorsque vous travaillez avec la construction
async/await
.
▍ Méthode Promise.prototype.finally ()
Si la promesse est résolue avec succès, la méthode
then()
est appelée. En cas de problème, la méthode
catch()
est appelée. La méthode
finally()
vous permet d'exécuter du code indépendamment de ce qui s'est passé auparavant.
fetch('file.json') .then(data => data.json()) .catch(error => console.error(error)) .finally(() => console.log('finished'))
▍ Améliorations de l'expression régulière
Les expressions régulières ont la capacité de vérifier rétrospectivement les chaînes (
?<=
). Cela vous permet de rechercher certaines constructions dans les lignes devant lesquelles il y a d'autres constructions.
La possibilité de précéder les vérifications à l'aide de la construction
?=
Était présente dans les expressions régulières implémentées en JavaScript avant la norme ES2018. Ces vérifications vous permettent de savoir si un autre fragment suit un certain fragment d'une ligne.
const r = /Roger(?= Waters)/ const res1 = r.test('Roger is my dog') const res2 = r.test('Roger is my dog and Roger Waters is a famous musician') console.log(res1)
Construction
?!
effectue l'opération inverse - une correspondance ne sera trouvée que si une autre ligne ne suit pas la ligne donnée.
const r = /Roger(?! Waters)/g const res1 = r.test('Roger is my dog') const res2 = r.test('Roger is my dog and Roger Waters is a famous musician') console.log(res1)
En vérification rétrospective, comme déjà mentionné, la construction
?<=
utilisée.
const r = /(?<=Roger) Waters/ const res1 = r.test('Pink Waters is my dog') const res2 = r.test('Roger is my dog and Roger Waters is a famous musician') console.log(res1)
L'opération opposée à celle décrite peut être effectuée en utilisant la construction
?<!
.
const r = /(?<!Roger) Waters/ const res1 = r.test('Pink Waters is my dog') const res2 = r.test('Roger is my dog and Roger Waters is a famous musician') console.log(res1)
Séquences d'échappement regex Unicode
Dans les expressions régulières, vous pouvez utiliser la classe
\d
qui correspond à n'importe quel chiffre, la classe
\s
qui correspond à n'importe quel caractère d'espacement, la classe
\w
qui correspond à n'importe quel caractère alphanumérique, etc. La fonctionnalité en question étend l'ensemble des classes qui peuvent être utilisées dans les expressions régulières, vous permettant de travailler avec des séquences Unicode. Nous parlons de la classe
\p{}
et de l'inverse de la classe
\P{}
.
En Unicode, chaque caractère possède un ensemble de propriétés. Ces propriétés sont indiquées entre accolades du groupe
\p{}
. Ainsi, par exemple, la propriété
Script
détermine la famille de langues à laquelle appartient un caractère, la propriété
ASCII
, logique, prend la valeur
true
pour les caractères ASCII, etc. Par exemple, nous verrons si certaines lignes ne contiennent que des caractères ASCII.
console.log(r.test('abc'))
La propriété
ASCII_Hex_Digit
n'est
true
que pour les caractères pouvant être utilisés pour écrire des nombres hexadécimaux.
const r = /^\p{ASCII_Hex_Digit}+$/u console.log(r.test('0123456789ABCDEF'))
Il existe de nombreuses autres propriétés similaires qui sont utilisées de la même manière que celle décrite ci-dessus. Parmi eux, les
Uppercase
, les
Lowercase
, l'
White_Space
, l'
Alphabetic
et les
Emoji
.
Par exemple, voici comment utiliser la propriété
Script
pour déterminer quel alphabet est utilisé dans une chaîne. Ici, nous vérifions la chaîne pour l'utilisation de l'alphabet grec.
const r = /^\p{Script=Greek}+$/u console.log(r.test('ελληνικά'))
Les détails sur ces propriétés peuvent être trouvés
ici .
Groupes nommés
Les groupes de caractères capturés dans ES2018 peuvent recevoir des noms. Voici à quoi ça ressemble.
const re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/ const result = re.exec('2015-01-02') console.log(result)
Sans l'utilisation de groupes nommés, les mêmes données ne seraient disponibles que sous forme d'éléments de tableau.
const re = /(\d{4})-(\d{2})-(\d{2})/ const result = re.exec('2015-01-02') console.log(result)
Drapeau regex s
L'utilisation du drapeau
s
donne un caractère
.
(point) correspondra, entre autres, au caractère de nouvelle ligne. Sans ce drapeau, un point correspond à n'importe quel caractère à l'exception d'une nouvelle ligne.
console.log(/hi.welcome/.test('hi\nwelcome'))
Résumé
Avec ce matériel, nous terminons la publication des traductions de
ce manuel JavaScript. Nous espérons que ces publications ont aidé ceux qui n'avaient pas travaillé avec JavaScript avant de faire leurs premiers pas dans la programmation dans ce langage.
Chers lecteurs! Si vous n'avez pas encore écrit en JS et maîtrisé cette langue dans ce guide, veuillez partager vos impressions.
