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
- Let et const
- Let vs var
- Let vs const
- Fonctions de flèche
- Le contenu des fonctions de flèche
- Le lexique this
- Paramètres par défaut
- Déstructuration
- Objets de déstructuration
- Tableaux de déstructuration
- Permutation de variables avec des tableaux déstructurés
- Déstructurer des tableaux et des objets tout en déclarant des fonctions
- Le paramètre rest et l’opérateur spread
- Le paramètre rest
- L’opérateur d’étalement
- Littéraux d’objets améliorés
- Abréviations de la valeur de la propriété
- Raccourci de méthode
- Noms de propriétés d’objet calculés
- Modèles littéraux
- Emballage
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:
- Let et const
- Fonctions de flèche
- Paramètres par défaut
- Déstructuration
- Paramètre de repos et opérateur de propagation
- Littéraux d’objet améliorés
- Littéraux de modèle
- 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
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)};
( 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)};
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:
- Le nombre d’arguments requis
- 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
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
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
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 this
lexical 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)
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:
- Valeur de propriété raccourcis
- Raccourci de méthode
- 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.
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`
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.