Introduction aux fonctionnalités ES6 couramment utilisées

10 mai 2017

JavaScript a beaucoup progressé ces dernières années. Si vous apprenez JavaScript en 2017 et que vous n’avez pas touché à ES6, vous manquez un moyen plus facile de lire et d’écrire JavaScript.

Ne vous inquiétez pas si vous n’êtes pas encore maître de JavaScript. Vous n’avez pas besoin d’être génial en JavaScript pour profiter des bonus ajoutés que vous offre ES6. Dans cet article, je veux partager avec vous huit fonctionnalités ES6 que j’utilise quotidiennement en tant que développeur pour vous aider à vous familiariser avec la nouvelle syntaxe.

Une liste des fonctionnalités ES6

Tout d’abord, ES6 est une énorme mise à jour de JavaScript. Voici une grande liste de fonctionnalités si vous êtes curieux de connaître les nouveautés, grâce à Luke Hoban:

  • Flèches
  • Classes
  • Littéraux d’objets améliorés
  • Chaînes de modèles
  • Déstructuration
  • Par défaut + rest + spread
  • Let +const
  • Itérateurs + pour… de
  • Générateurs
  • Unicode
  • Modules
  • Chargeurs de modules
  • Map+set+ weakmap+ weakset
  • Proxies
  • Symboles
  • Éléments intégrés sous-classables
  • Promesses
  • Api mathématiques + nombre + chaîne + tableau + objet
  • Littéraux binaires et octaux
  • Api Reflect
  • Queue appels

Ne laissez pas cette grande liste de fonctionnalités vous effrayer d’ES6. Vous n’avez pas besoin de tout savoir tout de suite. Je vais partager avec vous huit de ces fonctionnalités que j’utilise quotidiennement. Ils sont:

  1. Let et const
  2. Fonctions de flèche
  3. Paramètres par défaut
  4. Déstructuration
  5. Paramètre de repos et opérateur de propagation
  6. Littéraux d’objet améliorés
  7. Littéraux de modèle
  8. Promesses

Nous allons parcourez les huit fonctionnalités des sections suivantes. Pour l’instant, je vais passer en revue les cinq premières fonctionnalités. J’ajouterai le reste au fur et à mesure dans les deux prochaines semaines.

Au fait, la prise en charge du navigateur pour ES6 est incroyable. Presque tout est pris en charge en mode natif si vous codez pour les derniers navigateurs (Edge et les dernières versions de FF, Chrome et Safari).

Vous n’avez pas besoin d’outils sophistiqués comme Webpack si vous vouliez écrire ES6. Si le support du navigateur fait défaut dans votre cas, vous pouvez toujours vous rabattre sur les polyfills créés par la communauté. Il suffit de les google 🙂

Avec cela, passons à la première fonctionnalité.

Let et const

Dans ES5 (l’ancien JavaScript), nous avons l’habitude de déclarer des variables avec le mot-clé var. Dans ES6, ce mot-clé var peut être remplacé par let et const, deux mots-clés puissants qui simplifient le développement.

Regardons d’abord la différence entre let et var pour comprendre pourquoi let et const sont meilleurs.

Let vs var

Parlons d’abord de var puisque nous le connaissons bien.

Tout d’abord, nous pouvons déclarer des variables avec le mot clé var. Une fois déclarée, cette variable peut être utilisée n’importe où dans la portée actuelle.

var me = 'Zell'console.log(me) // Zell

Dans l’exemple ci-dessus, j’ai déclaré me comme variable globale. Cette variable globale me peut également être utilisée dans une fonction, comme celle-ci:

var me = 'Zell'function sayMe () { console.log(me)}sayMe() // Zell

Cependant, l’inverse n’est pas vrai. Si je déclare une variable dans une fonction, je ne peux pas l’utiliser en dehors de la fonction.

function sayMe() { var me = 'Zell' console.log(me)}sayMe() // Zellconsole.log(me) // Uncaught ReferenceError: me is not defined

Donc, on peut dire que var est à portée de fonction. Cela signifie que chaque fois qu’une variable est créée avec var dans une fonction, elle n’existera que dans la fonction.

Si la variable est créée en dehors de la fonction, elle existera dans la portée externe.

var me = 'Zell' // global scopefunction sayMe () { var me = 'Sleepy head' // local scope console.log(me)}sayMe() // Sleepy headconsole.log(me) // Zell

let, d’autre part, est à portée de bloc. Cela signifie que chaque fois qu’une variable est créée avec let, elle n’existera que dans son bloc.

Mais attendez, c’est quoi un bloc ?

Un bloc en JavaScript est tout ce qui se trouve dans une paire d’accolades. Voici des exemples de blocs.

{ // new scope block}if (true) { // new scope block}while (true) { // new scope block}function () { // new block scope}

La différence entre les variables à portée de bloc et à portée de fonction est énorme. Lorsque vous utilisez une variable à portée de fonction, vous pouvez écraser accidentellement une variable sans avoir l’intention de le faire. Voici un exemple:

var me = 'Zell'if (true) { var me = 'Sleepy head'}console.log(me) // 'Sleepy head'

Dans cet exemple, vous pouvez voir que me devient Sleepy head après avoir parcouru le bloc if. Cet exemple ne vous posera probablement aucun problème car vous ne déclarerez probablement pas de variables portant le même nom.

Mais toute personne qui travaille avec var dans une situation de boucle for peut rencontrer une certaine bizarrerie en raison de la façon dont les variables sont définies. Considérez le code suivant qui enregistre la variable i quatre fois, puis enregistre à nouveau i avec une fonction setTimeout.

for (var i = 1; i < 5; i++) { console.log(i) setTimeout(function () { console.log(i) }, 1000)};

Qu’attendez-vous de ce code ? Voici ce qui se passe réellement

 j'ai été connecté en tant que 5 quatre fois dans la fonction de délai d'attente
j’ai été connecté en tant que 5 quatre fois dans la fonction de délai d’attente

Comment diable i est-il devenu 5 quatre fois dans la fonction de délai d’attente? Eh bien, il s’avère que, parce que var est à portée de fonction, la valeur de i est devenue 4 avant même que la fonction de délai d’expiration ne s’exécute.

Pour obtenir la valeur i correcte dans setTimeout, qui s’exécute plus tard, nous devons créer une autre fonction, disons logLater, pour nous assurer que la valeur i n’est pas modifiée par la boucle for avant que setTimeout ne s’exécute:

function logLater (i) { setTimeout(function () { console.log(i) })}for (var i = 1; i < 5; i++) { console.log(i) logLater(i)};
 j'étais correctement connecté en tant que 1, 2 3 et 4
j’étais correctement connecté en tant que 1, 2 3 et 4

( Soit dit en passant, cela s’appelle une fermeture).

La bonne nouvelle est que l’étrangeté à portée de fonction comme l’exemple de boucle for que je viens de vous montrer ne se produit pas avec let. Le même exemple de délai d’attente que nous avons écrit plus tôt pourrait être écrit comme ceci, et cela fonctionnera dès la sortie de la boîte sans écrire de fonctions supplémentaires:

for (let i = 1; i < 5; i++) { console.log(i) setTimeout(function () { console.log(i) }, 1000)};
 j'étais correctement connecté en tant que 1, 2 3 et 4
j’étais correctement connecté en tant que 1, 2 3 et 4

Comme vous pouvez le voir, les variables à portée de bloc simplifient le développement en supprimant les pièges courants avec des variables à portée de fonction. Pour simplifier la vie, je vous recommande d’utiliser let sur var chaque fois que vous déclarez des variables JavaScript à partir de maintenant. (ES6 est déjà le nouveau JavaScript 😎).

Maintenant, nous savons ce que fait let, passons à la différence entre let et const.

Let vs const

Comme let, const est également bloqué. La différence est que const ne peut pas être réaffecté une fois déclaré.

const name = 'Zell'name = 'Sleepy head' // TypeError: Assignment to constant variable.let name1 = 'Zell'name1 = 'Sleepy head'console.log(name1) // 'Sleepy head'

Étant donné que const ne peut pas être réaffecté, ils sont bons pour que les variables ne changent pas.

Disons que j’ai un bouton qui lance un modal sur mon site Web. Je sais qu’il n’y aura qu’un seul bouton, et ça ne changerait pas. Dans ce cas, je peux utiliser const.

const modalLauncher = document.querySelector('.jsModalLauncher')

Lors de la déclaration de variables, je préfère toujours const à let dans la mesure du possible car je reçois le signal supplémentaire que la variable ne serait pas réaffectée. Ensuite, j’utilise let pour toutes les autres situations.

Ensuite, passons à autre chose et parlons des fonctions de flèche.

Fonctions de flèche

Les fonctions de flèche sont désignées par la flèche fat (=>) que vous voyez partout dans le code ES6. C’est un raccourci pour faire des fonctions anonymes. Ils peuvent être utilisés partout où le mot clé function est utilisé. Par exemple:

let array = // ES5 wayvar moreThan20 = array.filter(function (num) { return num > 20})// ES6 waylet moreThan20 = array.filter(num => num > 20)

Les fonctions de flèche sont assez cool. Ils aident à raccourcir le code, ce qui laisse moins de place aux erreurs à masquer. Ils vous aident également à écrire du code plus facile à comprendre une fois que vous vous êtes habitué à la syntaxe.

Plongeons dans les moindres détails des fonctions de flèche afin que vous appreniez à les reconnaître et à les utiliser.

Le contenu des fonctions de flèche

Tout d’abord, parlons de la création de fonctions. En JavaScript, vous êtes probablement habitué à créer des fonctions de cette façon:

function namedFunction() { // Do something}// using the functionnamedFunction()

Il existe une deuxième méthode pour créer des fonctions. Vous pouvez créer une fonction anonyme et l’affecter à une variable. Pour créer une fonction anonyme, nous laissons son nom en dehors de la déclaration de fonction.

var namedFunction = function() { // Do something}

Une troisième façon de créer des fonctions consiste à les créer directement en tant qu’argument d’une autre fonction ou méthode. Ce troisième cas d’utilisation est le plus courant pour les fonctions anonymes. Voici un exemple:

// Using an anonymous function in a callbackbutton.addEventListener('click', function() { // Do something})

Étant donné que les fonctions de flèche ES6 sont des raccourcis pour les fonctions anonymes, vous pouvez remplacer les fonctions de flèche partout où vous créez une fonction anonyme.

Voici à quoi cela ressemble:

// Normal Functionconst namedFunction = function (arg1, arg2) { /* do your stuff */}// Arrow Functionconst namedFunction2 = (arg1, arg2) => {/* do your stuff */}// Normal function in a callbackbutton.addEventListener('click', function () { // Do something})// Arrow function in a callbackbutton.addEventListener('click', () => { // Do something})

Voir la similitude ici? Fondamentalement, vous supprimez le mot clé function et le remplacez par => à un emplacement légèrement différent.

Mais quel est le problème avec les fonctions de flèche? Ne substituons-nous pas simplement function par =>?

Eh bien, il s’avère que nous ne remplaçons pas simplement function par =>. La syntaxe d’une fonction fléchée peut changer en fonction de deux facteurs:

  1. Le nombre d’arguments requis
  2. Si vous souhaitez un retour implicite.

Le premier facteur est le nombre d’arguments fournis à la fonction flèche. Si vous ne fournissez qu’un seul argument, vous pouvez supprimer la parenthèse qui entoure les arguments. Si aucun argument n’est requis, vous pouvez remplacer la parenthèse (()) par un trait de soulignement (_).

Toutes les fonctions suivantes sont des fonctions de flèche valides.

const zeroArgs = () => {/* do something */}const zeroWithUnderscore = _ => {/* do something */}const oneArg = arg1 => {/* do something */}const oneArgWithParenthesis = (arg1) => {/* do something */}const manyArgs = (arg1, arg2) => {/* do something */}

Le deuxième facteur pour les fonctions de flèche est de savoir si vous souhaitez un retour implicite. Les fonctions de flèche, par défaut, créent automatiquement un mot-clé return si le code ne prend qu’une ligne et n’est pas enfermé dans un bloc.

Donc, ces deux sont équivalents:

const sum1 = (num1, num2) => num1 + num2const sum2 = (num1, num2) => { return num1 + num2 }

Ces deux facteurs sont la raison pour laquelle vous pouvez écrire du code plus court comme le moreThan20 que vous avez vu ci-dessus:

let array = // ES5 wayvar moreThan20 = array.filter(function (num) { return num > 20})// ES6 waylet moreThan20 = array.filter(num => num > 20)

En résumé, les fonctions de flèche sont plutôt cool. Ils prennent un peu de temps pour s’y habituer, alors essayez-le et vous l’utiliserez bientôt partout.

Mais avant de vous lancer dans le train en marche des fonctions de flèche FTW, je veux vous faire part d’une autre caractéristique de la fonction de flèche ES6 qui cause beaucoup de confusion – le lexical this.

Le lexique this

this est un mot clé unique dont la valeur change en fonction de la façon dont il est appelé. Lorsqu’il est appelé en dehors d’une fonction, this est par défaut l’objet Window dans le navigateur.

console.log(this) // Window
 Cette valeur par défaut est l'objet window dans les navigateurs
Cette valeur par défaut est l’objet window dans les navigateurs

Lorsque this est appelé dans un simple appel de fonction, this est défini sur l’objet global. Dans le cas des navigateurs, this sera toujours Window.

function hello () { console.log(this)}hello() // Window

JavaScript définit toujours this sur l’objet window lors d’un simple appel de fonction. Cela explique pourquoi la valeur this dans des fonctions comme setTimeout est toujours Window.

Lorsque this est appelé dans une méthode object, this serait l’objet lui-même:

let o = { sayThis: function() { console.log(this) }}o.sayThis() // o
 Cela fait référence à l'objet lorsque la fonction est appelée dans une méthode d'objet.
Cela fait référence à l’objet lorsque la fonction est appelée dans une méthode objet.

Lorsque la fonction est appelée en tant que constructeur, this fait référence à l’objet nouvellement construit.

function Person (age) { this.age = age}let greg = new Person(22)let thomas = new Person(24)console.log(greg) // this.age = 22console.log(thomas) // this.age = 24
 Cela fait référence à l'objet construit appelé avec le nouveau mot-clé ou Objet.créer().
Cela fait référence à l’objet construit appelé avec le nouveau mot-clé ou Objet.créer().

Lorsqu’il est utilisé dans un écouteur d’événements, this est défini sur l’élément qui a déclenché l’événement.

let button = document.querySelector('button')button.addEventListener('click', function() { console.log(this) // button})

Comme vous pouvez le voir dans les situations ci-dessus, la valeur de this est définie par la fonction qui l’appelle. Chaque fonction définit sa propre valeur this.

Dans les fonctions fat arrow, this n’est jamais lié à une nouvelle valeur, quelle que soit la façon dont la fonction est appelée. this sera toujours la même valeur this que son code environnant. (En passant, les moyens lexicaux relatifs à, ce qui, je suppose, est la façon dont le lexical this a obtenu son nom).

D’accord, cela semble déroutant, alors passons en revue quelques exemples réels.

Tout d’abord, vous ne voulez plus utiliser de fonctions de flèche pour déclarer des méthodes d’objet, car vous ne pouvez plus référencer l’objet avec this.

let o = { // Don't do this notThis: () => { console.log(this) // Window this.objectThis() // Uncaught TypeError: this.objectThis is not a function }, // Do this objectThis: function () { console.log(this) // o } // Or this, which is a new shorthand objectThis2 () { console.log(this) // o }}

Deuxièmement, vous ne souhaitez peut-être pas utiliser les fonctions de flèche pour créer des écouteurs d’événements car this ne se lie plus à l’élément auquel vous avez attaché votre écouteur d’événements.

Cependant, vous pouvez toujours obtenir le bon contexte this avec event.currentTarget. C’est pourquoi j’ai dit que non.

button.addEventListener('click', function () { console.log(this) // button})button.addEventListener('click', e => { console.log(this) // Window console.log(event.currentTarget) // button})

Troisièmement, vous pouvez utiliser le thislexical aux endroits où la liaison this change sans que vous le souhaitiez. Un exemple est la fonction timeout, vous n’avez donc jamais à gérer les absurdités this, that ou self.

let o = { // Old way oldDoSthAfterThree: function () { let that = this setTimeout(function () { console.log(this) // Window console.log(that) // o }) }, // Arrow function way doSthAfterThree: function () { setTimeout(() => { console.log(this) // o }, 3000) }}

Ce cas d’utilisation est particulièrement utile si vous avez besoin d’ajouter ou de supprimer une classe après un certain temps écoulé:

let o = { button: document.querySelector('button') endAnimation: function () { this.button.classList.add('is-closing') setTimeout(() => { this.button.classList.remove('is-closing') this.button.classList.remove('is-open') }, 3000) }}

Enfin, n’hésitez pas à utiliser la fonction fat arrow n’importe où ailleurs pour rendre votre code plus propre et plus court, comme l’exemple moreThan20 que nous avons eu ci-dessus:

let array = let moreThan20 = array.filter(num => num > 20)

Passons à autre chose.

Paramètres par défaut

Paramètres par défaut dans ES6 well eh bien, nous donne un moyen de spécifier les paramètres par défaut lorsque nous définissons des fonctions. Passons en revue un exemple et vous verrez à quel point c’est utile.

Disons que nous créons une fonction qui annonce le nom d’un joueur d’une équipe. Si vous écrivez cette fonction dans ES5, elle sera similaire à ce qui suit:

function announcePlayer (firstName, lastName, teamName) { console.log(firstName + ' ' + lastName + ', ' + teamName)}announcePlayer('Stephen', 'Curry', 'Golden State Warriors')// Stephen Curry, Golden State Warriors

À première vue, ce code semble correct. Mais si nous devions annoncer un joueur qui n’est affilié à aucune équipe?

Le code actuel échoue de manière embarrassante si nous avons laissé teamName dehors:

announcePlayer('Zell', 'Liew')// Zell Liew, undefined

Je suis presque sûr que undefined n’est pas une équipe 😉.

Si le joueur n’est pas affilié, annoncer Zell Liew, unaffiliated serait plus logique que Zell Liew, undefined. Tu n’es pas d’accord ?

Pour que announcePlayer annonce Zell Liew, unaffiliated, une façon est de passer la chaîne unaffiliated en tant que teamName:

announcePlayer('Zell', 'Liew', 'unaffiliated')// Zell Liew, unaffiliated

Bien que cela fonctionne, nous pouvons faire mieux en refactorisant unaffiliated en announcePlayer en vérifiant si teamName est défini.

Dans la version ES5, vous pouvez refactoriser le code en quelque chose comme ceci:

function announcePlayer (firstName, lastName, teamName) { if (!teamName) { teamName = 'unaffiliated' } console.log(firstName + ' ' + lastName + ', ' + teamName)}announcePlayer('Zell', 'Liew')// Zell Liew, unaffiliatedannouncePlayer('Stephen', 'Curry', 'Golden State Warriors')// Stephen Curry, Golden State Warriors

Ou, si vous êtes plus averti avec les opérateurs ternaires, vous auriez pu choisir une version terser:

function announcePlayer (firstName, lastName, teamName) { var team = teamName ? teamName : 'unaffiliated' console.log(firstName + ' ' + lastName + ', ' + team)}

Dans ES6, avec les paramètres par défaut, nous pouvons ajouter un signe égal (=) chaque fois que nous définissons un paramètre. Si nous le faisons, ES6 utilise automatiquement cette valeur par défaut lorsque le paramètre n’est pas défini.

Donc, dans ce code ci-dessous, lorsque teamName n’est pas défini, il vaut par défaut unaffiliated:

const announcePlayer = (firstName, lastName, teamName = 'unaffiliated') => { console.log(firstName + ' ' + lastName + ', ' + teamName)}announcePlayer('Zell', 'Liew')// Zell Liew, unaffiliatedannouncePlayer('Stephen', 'Curry', 'Golden State Warriors')// Stephen Curry, Golden State Warriors

Plutôt cool, n’est-ce pas? 🙂

Encore une chose. Si vous souhaitez appeler la valeur par défaut, vous pouvez transmettre undefined manuellement. Ce passage manuel de undefined aide lorsque votre paramètre par défaut n’est pas le dernier argument d’une fonction.

announcePlayer('Zell', 'Liew', undefined)// Zell Liew, unaffiliated

C’est tout ce que vous devez savoir sur les paramètres par défaut. C’est simple et très utile 🙂

Déstructuration

La déstructuration est un moyen pratique d’extraire des valeurs des tableaux et des objets. Il y a des différences mineures entre le tableau de déstructuration et les objets, alors parlons-en séparément.

Objets de déstructuration

Disons que vous avez l’objet suivant:

const Zell = { firstName: 'Zell', lastName: 'Liew'}

Pour obtenir les firstName et lastName de Zell, vous deviez créer deux variables, puis affecter chaque variable à une valeur, comme ceci:

let firstName = Zell.firstName // Zelllet lastName = Zell.lastName // Liew

Avec la déstructuration, vous pouvez créer et affecter ces variables avec une seule ligne de code. Voici comment vous déstructurez les objets:

let { firstName, lastName } = Zellconsole.log(firstName) // Zellconsole.log(lastName) // Liew

Tu vois ce qui s’est passé ici ? En ajoutant des accolades ({}) lors de la déclaration des variables, nous demandons à JavaScript de créer les variables susmentionnées, puis d’affecter Zell.firstName à firstName et Zell.lastName à lastName respectivement.

C’est ce qui se passe sous le capot:

// What you writelet { firstName, lastName } = Zell// ES6 does this automaticallylet firstName = Zell.firstNamelet lastName = Zell.lastName

Maintenant, si un nom de variable est déjà utilisé, nous ne pouvons plus déclarer la variable (surtout si vous utilisez let ou const).

Les éléments suivants ne fonctionnent pas:

let name = 'Zell Liew'let course = { name: 'JS Fundamentals for Frontend Developers' // ... other properties}let { name } = course // Uncaught SyntaxError: Identifier 'name' has already been declared

Si vous rencontrez des situations comme celles ci-dessus, vous pouvez renommer les variables tout en les déstructurant avec un deux-points (:).

Dans cet exemple ci-dessous, je crée une variable courseName et lui attribue course.name.

let { name: courseName } = courseconsole.log(courseName) // JS Fundamentals for Frontend Developers// What ES6 does under the hood:let courseName = course.name

Encore une chose.

Ne vous inquiétez pas si vous essayez de déstructurer une variable qui n’est pas contenue dans un objet. Il reviendra juste undefined.

let course = { name: 'JS Fundamentals for Frontend Developers'}let { package } = courseconsole.log(package) // undefined

Mais attendez, ce n’est pas tout. Vous vous souvenez des paramètres par défaut?

Vous pouvez également écrire des paramètres par défaut pour vos variables déstructurées. La syntaxe est la même que lorsque vous définissez des fonctions.

let course = { name: 'JS Fundamentals for Frontend Developers'}let { package = 'full course' } = courseconsole.log(package) // full course

Vous pouvez même renommer des variables tout en fournissant des valeurs par défaut. Il suffit de combiner les deux. Cela aura l’air un peu drôle au début, mais vous vous y habituerez si vous l’utilisez souvent:

let course = { name: 'JS Fundamentals for Frontend Developers'}let { package: packageName = 'full course' } = courseconsole.log(packageName) // full course

C’est tout pour déstructurer les objets. Passons à autre chose et parlons de la déstructuration des tableaux 😄.

Tableaux de déstructuration

Les tableaux de déstructuration et les objets de déstructuration sont similaires. Nous utilisons des crochets () au lieu de crochets ({}).

Lorsque vous déstructurez un tableau,

  • Votre première variable est le premier élément du tableau.
  • Votre deuxième variable est le deuxième élément du tableau.
  • et ainsi de suite…
let = console.log(one) // 1console.log(two) // 2

Il est possible de déstructurer autant de variables que vous dépassez le nombre d’éléments dans le tableau donné. Lorsque cela se produit, la variable déstructurée supplémentaire sera juste undefined.

let = console.log(one) // 1console.log(two) // 2console.log(three) // undefined

Lors de la déstructuration des tableaux, nous ne déstructurons souvent que les variables dont nous avons besoin. Si vous avez besoin du reste du tableau, vous pouvez utiliser l’opérateur rest (...), comme ceci:

let scores = let = scoresconsole.log(first) // 98console.log(second) // 95console.log(third) // 93console.log(rest) // 

Nous parlerons plus des opérateurs de repos dans la section suivante. Mais pour l’instant, parlons d’une capacité unique que vous obtenez avec des tableaux déstructurés – l’échange de variables.

Permutation de variables avec des tableaux déstructurés

Supposons que vous ayez deux variables, a et b.

let a = 2let b = 3

Vous vouliez échanger ces variables. Donc a = 3 et b = 2. Dans ES5, vous devez utiliser une troisième variable temporaire pour terminer l’échange:

let a = 2let b = 3let temp// swappingtemp = a // temp is now 2a = b // a is now 3b = temp // b is now 2

Bien que cela fonctionne, la logique peut être floue et déroutante, en particulier avec l’introduction d’une troisième variable.

Regardez maintenant comment vous allez le faire à la manière ES6 avec des tableaux déstructurés:

let a = 2let b = 3; // semicolon required because next line begins with a square bracket// Swapping with destructured arrays = console.log(a) // 3console.log(b) // 2

💥💥💥. Tellement plus simple par rapport à la méthode précédente d’échange de variables! 🙂

Ensuite, parlons de la déstructuration des tableaux et des objets dans une fonction.

Déstructurer des tableaux et des objets tout en déclarant des fonctions

La chose la plus cool à propos de la déstructuration est que vous pouvez les utiliser n’importe où. Littéralement. Vous pouvez même déstructurer des objets et des tableaux dans des fonctions.

Disons que nous avons une fonction qui prend un tableau de scores et renvoie un objet avec les trois meilleurs scores. Cette fonction est similaire à ce que nous avons fait lors de la déstructuration des tableaux.

// Note: You don't need arrow functions to use any other ES6 featuresfunction topThree (scores) { let = scores return { first: first, second: second, third: third }}

Une autre façon d’écrire cette fonction consiste à déstructurer scores tout en déclarant la fonction. Dans ce cas, il y a une ligne de code de moins à écrire. En même temps, nous savons que nous prenons un tableau.

function topThree () { return { first: first, second: second, third: third }}

Super cool, n’est-ce pas? 😄.

Maintenant, voici un petit quiz rapide pour vous. Puisque nous pouvons combiner les paramètres par défaut et la déstructuration tout en déclarant des fonctions, que dit ce qui suit?

function sayMyName ({ firstName = 'Zell', lastName = 'Liew'} = {}) { console.log(firstName + ' ' + lastName)}

Ceci est délicat. Nous combinons quelques fonctionnalités ensemble.

Tout d’abord, nous pouvons voir que cette fonction prend un argument, un objet. Cet objet est facultatif et par défaut {} lorsqu’il n’est pas défini.

Deuxièmement, nous essayons de déstructurer les variables firstName et lastName de l’objet donné. Si ces propriétés sont trouvées, utilisez-les.

Enfin, si firstName ou lastName n’est pas défini dans l’objet donné, nous le définissons respectivement sur Zell et Liew.

Ainsi, cette fonction produit les résultats suivants:

sayMyName() // Zell LiewsayMyName({firstName: 'Zell'}) // Zell LiewsayMyName({firstName: 'Vincy', lastName: 'Zhang'}) // Vincy Zhang

Assez cool de combiner la déstructuration et les paramètres par défaut dans une déclaration de fonction hein? 😄. J’adore ça.

Ensuite, jetons un coup d’œil au repos et à la propagation.

Le paramètre rest et l’opérateur spread

Le paramètre rest et l’opérateur spread se ressemblent. Ils sont tous deux signalés par trois points (...).

Ce qu’ils font est différent en fonction de ce pour quoi ils sont utilisés. C’est pourquoi ils sont nommés différemment. Jetons donc un coup d’œil au paramètre rest et étalons l’opérateur séparément.

Le paramètre rest

Traduit de manière lâche, le paramètre rest signifie prendre le reste de la substance et l’emballer dans un tableau. Il convertit une liste d’arguments séparés par des virgules en un tableau.

Jetons un coup d’œil au paramètre rest en action. Imaginez que nous ayons une fonction, add, qui résume ses arguments:

sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) // 55

Dans ES5, nous dépendions de la variable arguments chaque fois que nous devions faire face à une fonction qui prend un nombre inconnu de variables. Cette variable arguments est un tableau Symbol.

function sum () { console.log(arguments)}sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
 Arguments est un symbole, pas un tableau
Arguments est un symbole, pas un tableau

Une façon de calculer cette somme d’arguments est de la convertir en un tableau avec Array.prototype.slice.call(arguments), puis de parcourir chaque nombre avec une méthode de tableau comme forEach ou reduce.

Je suis sûr que vous pouvez faire forEach par vous-même, voici donc l’exemple reduce:

// ES5 wayfunction sum () { let argsArray = Array.prototype.slice.call(arguments) return argsArray.reduce(function(sum, current) { return sum + current }, 0)}

Avec le paramètre rest ES6, nous pourrions emballer tous les arguments séparés par des virgules directement dans un tableau.

// ES6 wayconst sum = (...args) => args.reduce((sum, current) => sum + current, 0)// ES6 way if we didn't shortcut it with so many arrow functionsfunction sum (...args) { return args.reduce((sum, current) => sum + current, 0)}

Beaucoup plus propre? 🙂.

Maintenant, nous avons brièvement rencontré le paramètre rest plus tôt dans la section déstructuration. Là, nous avons essayé de déstructurer un tableau de scores dans les trois meilleurs scores:

let scores = let = scoresconsole.log(first) // 98console.log(second) // 95console.log(third) // 93

Si nous voulions le reste des scores, nous pourrions le faire en emballant le reste des scores dans un tableau avec le paramètre rest.

let scores = let = scoresconsole.log(restOfScores) // 

Si jamais vous êtes confus, rappelez—vous ceci – le paramètre rest emballe tout dans un tableau. Il apparaît dans les paramètres de fonction et lors de la déstructuration des tableaux.

Ensuite, passons à la propagation.

L’opérateur d’étalement

L’opérateur d’étalement se comporte de manière opposée par rapport au paramètre rest. En termes lâches, il prend un tableau et le répartit (comme du jam) dans une liste d’arguments séparés par des virgules.

let array = // These two are exactly the sameconsole.log(...array) // one two threeconsole.log('one', 'two', 'three') // one two three

L’opérateur de propagation est souvent utilisé pour aider à concaténer les tableaux d’une manière plus facile à lire et à comprendre.

Par exemple, vous vouliez concaténer les tableaux suivants:

let array1 = let array2 = let array3 = 

La façon ES5 de concaténer ces deux tableaux consiste à utiliser la méthode Array.concat. Vous pouvez enchaîner plusieurs Array.concat pour concaténer un nombre quelconque de tableaux, comme ceci:

// ES5 waylet combinedArray = array1.concat(array2).concat(array3)console.log(combinedArray) // 

Avec l’opérateur de propagation ES6, vous pouvez répartir les tableaux dans un nouveau tableau, comme celui-ci, ce qui est légèrement plus facile à lire une fois que vous vous y êtes habitué:

// ES6 waylet combinedArray = console.log(combinedArray) // 

L’opérateur de propagation peut également être utilisé pour supprimer un élément d’un tableau sans muter le tableau. Cette méthode est couramment utilisée dans Redux. Je vous recommande fortement de regarder cette vidéo de Dan Abramov si vous souhaitez voir comment cela fonctionne.

C’est tout pour la propagation 🙂

Littéraux d’objets améliorés

Les objets doivent vous être familiers puisque vous écrivez du JavaScript. Juste au cas où vous ne le sauriez pas, ils ressemblent à ceci:

const anObject = { property1: 'value1', property2: 'value2', property3: 'value3',}

ES6 enhanced object literals apporte trois améliorations douces aux objets que vous connaissez et aimez. Ils sont:

  1. Valeur de propriété raccourcis
  2. Raccourci de méthode
  3. La possibilité d’utiliser des noms de propriétés calculés

Examinons chacun d’eux. Je promets que ce sera rapide 🙂

Abréviations de la valeur de la propriété

Avez-vous remarqué que vous attribuez parfois une variable qui a le même nom qu’une propriété d’objet? Tu sais, quelque chose comme ça:

const fullName = 'Zell Liew'const Zell = { fullName: fullName}

Eh bien, ne voudriez-vous pas pouvoir écrire cela de manière plus courte, puisque la propriété (fullName) et la valeur (fullName)?

(Oh tu as gâté gosse 😝).

Voici la bonne nouvelle. Tu peux ! 🙂

ES6 améliore les objets avec des raccourcis de valeur de propriété. Cela signifie : vous ne pouvez écrire la variable que si le nom de votre variable correspond à celui de votre propriété. ES6 s’occupe du reste.

Voici à quoi cela ressemble:

const fullName = 'Zell Liew'// ES6 wayconst Zell = { fullName}// Underneath the hood, ES6 does this:const Zell = { fullName: fullName}

Plutôt soigné, hein ? Maintenant, nous avons moins de mots à écrire, et nous rentrons tous heureux à la maison.

 Figurine joyeuse et dansante de star Wars
Wheeeee! Heureux! 🙂

Pendant que je danse, continuez et passez à plus de bonté abrégée. Je vous rejoindrai sous peu.

Raccourci de méthode

Les méthodes sont des fonctions associées à une propriété. Ils sont juste nommés spécialement parce que ce sont des fonctions 🙂

Ceci est un exemple de méthode:

const anObject = { aMethod: function () { console.log("I'm a method!~~")}}

Avec ES6, nous arrivons à écrire des méthodes avec un raccourci. Nous pouvons supprimer : function d’une déclaration de méthode et cela fonctionnera comme avant:

const anObject = { // ES6 way aShorthandMethod (arg1, arg2) {}, // ES5 way aLonghandMethod: function (arg1, arg2) {},}

Avec cette mise à niveau, les objets reçoivent déjà une méthode abrégée, veuillez donc ne pas utiliser de fonctions de flèche lorsque vous définissez des objets. Vous casserez le contexte this (voir fonctions de flèche si vous ne vous souvenez pas pourquoi).

const dontDoThis = { // Noooo. Don't do this arrowFunction: () => {}}

C’est tout avec les raccourcis de la méthode objet. Passons à la mise à niveau finale que nous obtenons pour les objets.

Noms de propriétés d’objet calculés

Parfois, vous avez besoin d’un nom de propriété dynamique lorsque vous créez des objets. Dans l’ancienne méthode JavaScript, vous devez créer l’objet, puis attribuer votre propriété à in, comme ceci:

// ES5const newPropertyName = 'smile'// Create an object firstconst anObject = { aProperty: 'a value' }// Then assign the propertyanObject = ':D'// Adding a slightly different property and assigning itanObject = 'XD'// Result// {// aProperty: 'a value',// 'bigger smile': 'XD'// smile: ':D',// }

Dans ES6, vous n’avez plus besoin de faire ce chemin de rond-point. Vous pouvez attribuer des noms de propriétés dynamiques directement lors de la création de votre objet. La clé est de placer la propriété dynamique entre crochets:

const newPropertyName = 'smile'// ES6 way.const anObject = { aProperty: 'a value', // Dynamic property names! : ':D', : 'XD',}// Result// {// aProperty: 'a value',// 'bigger smile': 'XD'// smile: ':D',// }

Schweeet! N’est-ce pas? 🙂

Et c’est tout pour les littéraux d’objets améliorés. N’ai-je pas dit que ce serait rapide? 🙂

Passons à une autre fonctionnalité géniale que j’adore: les littéraux de modèles.

Modèles littéraux

La gestion des chaînes en JavaScript est une expérience extrêmement maladroite. Vous l’avez expérimenté vous-même lorsque nous avons créé la fonction announcePlayer précédemment dans les paramètres par défaut. Là, nous avons créé des espaces avec des chaînes vides et les avons joints avec des avantages:

function announcePlayer (firstName, lastName, teamName) { console.log(firstName + ' ' + lastName + ', ' + teamName)}

Dans ES6, ce problème disparaît grâce aux littéraux de modèles! (Dans la spécification, ils étaient auparavant appelés chaînes de modèle).

Pour créer un littéral de modèle dans ES6, vous entourez des chaînes de caractères arrière (`). Dans les backticks, vous avez accès à un espace réservé spécial (${}) où vous pouvez utiliser JavaScript normalement.

Voici à quoi cela ressemble en action:

const firstName = 'Zell'const lastName = 'Liew'const teamName = 'unaffiliated'const theString = `${firstName} ${lastName}, ${teamName}`console.log(theString)// Zell Liew, unaffiliated

Tu vois ça ? Nous pouvons tout regrouper avec des modèles de littéraux! Dans les littéraux de modèles, c’est l’anglais comme d’habitude. Presque comme si nous utilisions un moteur de modèles 🙂

La meilleure partie des littéraux de modèles est que vous pouvez facilement créer des chaînes multi-lignes. Cela fonctionne dès la sortie de la boîte:

const multi = `One upon a time,In a land far far away,there lived a witich,who could change night into day`
 Chaînes multilignes !
Les chaînes multi-lignes fonctionnent! Woot!

Une astuce intéressante consiste à utiliser ces chaînes pour créer des éléments HTML en JavaScript si vous en avez besoin. (Remarque: Ce n’est peut-être pas le meilleur moyen de créer des éléments HTML, mais c’est toujours bien mieux que de les créer un par un!).

const container = document.createElement('div')const aListOfItems = `<ul> <li>Point number one</li> <li>Point number two</li> <li>Point number three</li> <li>Point number four</li> </ul>`container.innerHTML = aListOfItemsdocument.body.append(container)

Voir le stylet Utilisant des chaînes multi-lignes pour créer des éléments HTML plus compliqués par Zell Liew (@zellwk) sur CodePen.

Une autre caractéristique des littéraux de modèle est appelée balises. Les balises sont des fonctions qui vous permettent de manipuler le littéral du modèle, si vous souhaitez remplacer une chaîne.

Voici à quoi cela ressemble:

const animal = 'lamb'// This a tagconst tagFunction = () => { // Do something here}// This tagFunction allows you to manipulate the template literal.const string = tagFunction `Mary had a little ${animal}`

Pour être honnête, même si les balises de modèle ont l’air cool, je n’ai pas encore eu de cas d’utilisation pour elles. Si vous souhaitez en savoir plus sur les balises de modèle, je vous suggère de lire cette référence sur MDN.

C’est tout pour les littéraux de modèle.

Emballage

Woo! C’est presque toutes les fonctionnalités géniales de l’ES6 que j’utilise régulièrement. ES6 est génial. Cela vaut vraiment la peine de prendre un peu de votre temps et d’en apprendre davantage sur eux, afin que vous puissiez comprendre ce que tout le monde écrit.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.