One place for hosting & domains

      Comprendre

      Comprendre la déstructuration, les paramètres de rest et la syntaxe Spread en JavaScript


      L’auteur a choisi le COVID-19 Relief Fund pour recevoir un don dans le cadre du programme Write for DOnations.

      Introduction

      De nombreuses nouvelles fonctionnalités permettant de travailler avec des tableaux et des objets ont été mises à la disposition du langage JavaScript depuis l’édition 2015 de la spécification ECMAScript. Quelques-uns des éléments notables que vous apprendrez dans cet article sont la déstructuration, les paramètres de rest et la syntaxe de spread. Ces fonctionnalités fournissent des moyens plus directs d’accéder aux membres d’un tableau ou d’un objet, et peuvent rendre le travail avec ces structures de données plus rapide et plus succinct.

      De nombreux autres langages n’ont pas de syntaxe correspondante pour la déstructuration, les paramètres de rest et spread, de sorte que ces caractéristiques peuvent avoir une courbe d’apprentissage à la fois pour les nouveaux développeurs JavaScript et ceux qui viennent d’un autre langage. Dans cet article, vous apprendrez comment déstructurer des objets et des tableaux, comment utiliser l’opérateur de spread pour décompresser des objets et des tableaux, et comment utiliser les paramètres de rest dans les appels de fonction.

      Déstructurer

      L’affectation de déstructuration est une syntaxe qui vous permet d’affecter des propriétés d’objets ou des éléments de tableau comme variables. Cela peut réduire considérablement les lignes de code nécessaires pour manipuler les données dans ces structures. Il existe deux types de déstructuration : Déstructuration d’objets et déstructuration des tableaux.

      Déstructuration d’objets

      La déstructuration d’objets vous permet de créer de nouvelles variables en utilisant une propriété de l’objet comme valeur.

      Prenons cet exemple, un objet qui représente une note avec une id, un titre et une date :

      const note = {
        id: 1,
        title: 'My first note',
        date: '01/01/1970',
      }
      

      Traditionnellement, si vous vouliez créer une nouvelle variable pour chaque propriété, vous deviez affecter chaque variable individuellement, avec beaucoup de répétition :

      // Create variables from the Object properties
      const id = note.id
      const title = note.title
      const date = note.date
      

      Avec la déstructuration des objets, tout cela peut être fait en une seule ligne. En entourant chaque variable d’accolades {}, JavaScript créera de nouvelles variables à partir de chaque propriété portant le même nom :

      // Destructure properties into variables
      const { id, title, date } = note
      

      Maintenant, console.log() les nouvelles variables :

      console.log(id)
      console.log(title)
      console.log(date)
      

      Vous obtiendrez les valeurs initiales des valeurs des propriétés comme résultat :

      Output

      1 My first note 01/01/1970

      Note : La déstructuration d’un objet ne modifie pas l’objet original. Vous pouvez toujours appeler la note originale avec toutes ses entrées intactes.

      L’affectation par défaut pour la déstructuration des objets crée de nouvelles variables portant le même nom que la propriété de l’objet. Si vous ne souhaitez pas que la nouvelle variable ait le même nom que le nom de la propriété, vous avez également la possibilité de renommer la nouvelle variable en utilisant deux-points ( : ) pour décider d’un nouveau nom, comme on le verra avec la noteId dans ce qui suit :

      // Assign a custom name to a destructured value
      const { id: noteId, title, date } = note
      

      Enregistrez la nouvelle variable noteId dans la console :

      console.log(noteId)
      

      Vous recevrez le résultat suivant :

      Output

      1

      Vous pouvez également déstructurer les valeurs d’objets imbriqués. Par exemple, mettez à jour l’objet note pour avoir un objet auteur imbriqué :

      const note = {
        id: 1,
        title: 'My first note',
        date: '01/01/1970',
        author: {
          firstName: 'Sherlock',
          lastName: 'Holmes',
        },
      }
      

      Vous pouvez maintenant déstructurer note, puis déstructurer à nouveau pour créer des variables à partir des propriétés de l'auteur :

      // Destructure nested properties
      const {
        id,
        title,
        date,
        author: { firstName, lastName },
      } = note
      

      Ensuite, enregistrez les nouvelles variables firstName et lastName en utilisant les littéraux du modèle :

      console.log(`${firstName} ${lastName}`)
      

      Cela donnera le résultat suivant :

      Output

      Sherlock Holmes

      Notez que dans cet exemple, bien que vous ayez accès au contenu de l’objet auteur, l’objet auteur lui-même n’est pas accessible. Pour accéder à un objet ainsi qu’à ses valeurs imbriquées, il faudrait les déclarer séparément :

      // Access object and nested values
      const {
        author,
        author: { firstName, lastName },
      } = note
      
      console.log(author)
      

      Ce code produira l’objet author:

      Output

      {firstName: "Sherlock", lastName: "Holmes"}

      La déstructuration d’un objet n’est pas seulement utile pour réduire la quantité de code que vous devez écrire ; elle vous permet également de cibler votre accès aux propriétés qui vous intéressent.

      Enfin, déstructurer peut être utilisé pour accéder aux propriétés des objets des valeurs primitives. Par exemple, String est un objet global pour les chaînes de caractères, et possède une propriété de longueur :

      const { length } = 'A string'
      

      Cela permettra de trouver la propriété de longueur inhérente d’une chaîne et de la rendre égale à la variable de longueur. Enregistrez la longueur pour voir si cela a fonctionné :

      console.log(length)
      

      Vous aurez le résultat suivant :

      Output

      8

      La chaîne A string a été implicitement convertie en un objet ici pour récupérer la propriété de longueur.

      Déstructuration des tableaux

      La déstructuration des tableaux vous permet de créer de nouvelles variables en utilisant un élément de tableau comme valeur. Prenons cet exemple, un tableau avec les différentes parties d’une date :

      const date = ['1970', '12', '01']
      

      Les tableaux en JavaScript sont garantis pour préserver leur ordre, donc dans ce cas le premier indice sera toujours une année, le second sera le mois, et ainsi de suite. Sachant cela, vous pouvez créer des variables à partir des éléments du tableau :

      // Create variables from the Array items
      const year = date[0]
      const month = date[1]
      const day = date[2]
      

      Mais le faire manuellement peut prendre beaucoup de place dans votre code. Avec la déstructuration des tableaux, vous pouvez décomposer les valeurs du tableau dans l’ordre et les affecter à leurs propres variables, comme ceci :

      // Destructure Array values into variables
      const [year, month, day] = date
      

      Enregistrez maintenant les nouvelles variables :

      console.log(year)
      console.log(month)
      console.log(day)
      

      Vous aurez le résultat suivant :

      Output

      1970 12 01

      Les valeurs peuvent être sautées en laissant la syntaxe de déstructuration vide entre les virgules :

      // Skip the second item in the array
      const [year, , day] = date
      
      console.log(year)
      console.log(day)
      

      L’exécution de cette opération donnera la valeur de l'année et du jour :

      Output

      1970 01

      Les tableaux imbriqués peuvent également être déstructurés. Tout d’abord, créez un tableau imbriqué :

      // Create a nested array
      const nestedArray = [1, 2, [3, 4], 5]
      

      Ensuite, déstructurez ce tableau et enregistrez les nouvelles variables :

      // Destructure nested items
      const [one, two, [three, four], five] = nestedArray
      
      console.log(one, two, three, four, five)
      

      Vous recevrez le résultat suivant :

      Output

      1 2 3 4 5

      La syntaxe de déstructuration peut être appliquée pour déstructurer les paramètres d’une fonction. Pour tester cela, vous déstructurez les clés et les valeurs à partir de Object.entries().

      Déclarez d’abord l’objet de la note :

      const note = {
        id: 1,
        title: 'My first note',
        date: '01/01/1970',
      }
      

      Étant donné cet objet, vous pourriez dresser la liste des paires clé-valeur en déstructurant les arguments au fur et à mesure qu’ils sont passés à la méthode forEach() :

      // Using forEach
      Object.entries(note).forEach(([key, value]) => {
        console.log(`${key}: ${value}`)
      })
      

      Ou vous pourriez faire la même chose en utilisant une boucle for :

      // Using a for loop
      for (let [key, value] of Object.entries(note)) {
        console.log(`${key}: ${value}`)
      }
      

      Dans tous les cas, vous recevrez ce qui suit :

      Output

      id: 1 title: My first note date: 01/01/1970

      La déstructuration d’objets et la déstructuration de tableaux peuvent être combinées en une seule affectation de déstructuration. Les paramètres par défaut peuvent également être utilisés avec la déstructuration, comme le montre cet exemple qui fixe la date par défaut à new Date().

      Déclarez d’abord l’objet de la note :

      const note = {
        title: 'My first note',
        author: {
          firstName: 'Sherlock',
          lastName: 'Holmes',
        },
        tags: ['personal', 'writing', 'investigations'],
      }
      

      Puis déstructurez l’objet, tout en définissant une nouvelle variable de date avec la valeur par défaut de new Date() :

      const {
        title,
        date = new Date(),
        author: { firstName },
        tags: [personalTag, writingTag],
      } = note
      
      console.log(date)
      

      console.log(date) donnera alors un résultat similaire à ce qui suit :

      Output

      Fri May 08 2020 23:53:49 GMT-0500 (Central Daylight Time)

      Comme le montre cette section, la syntaxe de l’affectation de déstructuration ajoute beaucoup de souplesse à JavaScript et permet d’écrire un code plus succinct. Dans la section suivante, vous verrez comment la syntaxe de spread peut être utilisée pour étendre les structures de données dans leurs entrées de données constitutives.

      Spread

      La syntaxe Spread (...) est un autre ajout utile au JavaScript pour travailler avec des tableaux, des objets et des appels de fonction. Spread permet de déballer ou d’étendre des objets et des itérables (tels que des tableaux), qui peuvent être utilisés pour faire des copies superficielles de structures de données afin d’accroître la facilité de manipulation des données.

      Spread avec des tableaux

      Spread peut simplifier les tâches courantes avec les tableaux. Par exemple, disons que vous avez deux tableaux et que vous voulez les combiner :

      // Create an Array
      const tools = ['hammer', 'screwdriver']
      const otherTools = ['wrench', 'saw']
      

      A l’origine, vous deviez utiliser concat() pour concaténer les deux tableaux :

      // Concatenate tools and otherTools together
      const allTools = tools.concat(otherTools)
      

      Désormais, vous pouvez également utiliser spread pour déballer les tableaux dans un nouveau tableau :

      // Unpack the tools Array into the allTools Array
      const allTools = [...tools, ...otherTools]
      
      console.log(allTools)
      

      L’exécution de cette opération donnerait les résultats suivants :

      Output

      ["hammer", "screwdriver", "wrench", "saw"]

      Cela peut être particulièrement utile en cas d’immuabilité. Par exemple, vous pourriez travailler avec une application dont les utilisateurs sont stockés dans un ensemble d’objets : 

      // Array of users
      const users = [
        { id: 1, name: 'Ben' },
        { id: 2, name: 'Leslie' },
      ]
      

      Vous pourriez utiliserpush pour modifier le tableau existant et ajouter un nouvel utilisateur, ce qui serait l’option mutable :

      // A new user to be added
      const newUser = { id: 3, name: 'Ron' }
      
      users.push(newUser)
      

      Mais cela change le tableau user, que nous pourrions vouloir conserver.

      Spread vous permet de créer un nouveau tableau à partir de celui qui existe déjà et d’ajouter un nouvel élément à la fin :

      const updatedUsers = [...users, newUser]
      
      console.log(users)
      console.log(updatedUsers)
      

      Maintenant, le nouveau tableau, updatedUsers, a le nouvel utilisateur, mais le tableau original users reste inchangé :

      Output

      [{id: 1, name: "Ben"} {id: 2, name: "Leslie"}] [{id: 1, name: "Ben"} {id: 2, name: "Leslie"} {id: 3, name: "Ron"}]

      Créer des copies de données au lieu de modifier les données existantes peut aider à prévenir les changements inattendus. En JavaScript, lorsque vous créez un objet ou un tableau et que vous l’affectez à une autre variable, vous ne créez pas réellement un nouvel objet – vous passez une référence.

      Prenez cet exemple, dans lequel un tableau est créé et assigné à une autre variable :

      // Create an Array
      const originalArray = ['one', 'two', 'three']
      
      // Assign Array to another variable
      const secondArray = originalArray
      

      Supprimer le dernier élément du deuxième tableau modifiera le premier :

      // Remove the last item of the second Array
      secondArray.pop()
      
      console.log(originalArray)
      

      Cela donnera le résultat :

      Output

      ["one", "two"]

      Spread vous permet de faire une copie superficielle d’un tableau ou d’un objet, ce qui signifie que toutes les propriétés de haut niveau seront clonées, mais que les objets imbriqués seront toujours passés par référence. Pour les tableaux ou objets simples, une copie superficielle peut suffire.

      Si vous écrivez le même exemple de code mais copiez le tableau avec spread, le tableau original ne sera plus modifié :

      // Create an Array
      const originalArray = ['one', 'two', 'three']
      
      // Use spread to make a shallow copy
      const secondArray = [...originalArray]
      
      // Remove the last item of the second Array
      secondArray.pop()
      
      console.log(originalArray)
      

      Les éléments suivants seront enregistrés sur la console :

      Output

      ["one", "two", "three"]

      Spread peut également être utilisé pour convertir un set, ou tout autre iterable, en un tableau.

      Créez un nouvel ensemble et ajoutez-y quelques entrées :

      // Create a set
      const set = new Set()
      
      set.add('octopus')
      set.add('starfish')
      set.add('whale')
      

      Ensuite, utilisez l’opérateur spread avec set et enregistrez les résultats :

      // Convert Set to Array
      const seaCreatures = [...set]
      
      console.log(seaCreatures)
      

      Cela donnera le résultat :

      Output

      ["octopus", "starfish", "whale"]

      Cela peut également être utile pour créer un tableau à partir d’une chaîne de caractères :

      const string = 'hello'
      
      const stringArray = [...string]
      
      console.log(stringArray)
      

      Cela donnera un tableau avec chaque caractère en tant qu’élément dans le tableau :

      Output

      ["h", "e", "l", "l", "o"]

      Spread avec objets

      Lorsqu’on travaille avec des objets, spread peut être utilisé pour copier et mettre à jour les objets.

      A l’origine, Object.assign() était utilisé pour copier un objet :

      // Create an Object and a copied Object with Object.assign()
      const originalObject = { enabled: true, darkMode: false }
      const secondObject = Object.assign({}, originalObject)
      

      Le secondObject sera désormais un clone de l’originalObject.

      La syntaxe de spread simplifie cette opération (vous pouvez copier un objet superficiellement en l’étalant dans un nouvel objet) :

      // Create an object and a copied object with spread
      const originalObject = { enabled: true, darkMode: false }
      const secondObject = { ...originalObject }
      
      console.log(secondObject)
      

      Ce qui donnera le résultat suivant :

      Output

      {enabled: true, darkMode: false}

      Tout comme pour les tableaux, cela ne créera qu’une copie superficielle, et les objets imbriqués seront toujours passés par référence.

      L’ajout ou la modification de propriétés sur un objet existant de manière immuable est simplifié avec spread. Dans cet exemple, la propriété isLoggedIn est ajoutée à l’objet user:

      const user = {
        id: 3,
        name: 'Ron',
      }
      
      const updatedUser = { ...user, isLoggedIn: true }
      
      console.log(updatedUser)
      

      Il en résultera ce qui suit :

      Output

      {id: 3, name: "Ron", isLoggedIn: true}

      Une chose importante à noter concernant la mise à jour des objets spread est que tout objet imbriqué devra également être diffusé. Par exemple, disons que dans l’objet user, il y a un objet organisationnel imbriqué :

      const user = {
        id: 3,
        name: 'Ron',
        organization: {
          name: 'Parks & Recreation',
          city: 'Pawnee',
        },
      }
      

      Si vous essayez d’ajouter un nouvel élément à l’organisation, il écrasera les champs existants : 

      const updatedUser = { ...user, organization: { position: 'Director' } }
      
      console.log(updatedUser)
      

      Ce qui donnera le résultat suivant :

      Output

      id: 3 name: "Ron" organization: {position: "Director"}

      Si la mutabilité n’est pas un problème, le champ pourrait être mis à jour directement :

      user.organization.position = 'Director'
      

      Mais comme nous recherchons une solution immuable, nous pouvons diffuser l’objet intérieur pour conserver les propriétés existantes :

      const updatedUser = {
        ...user,
        organization: {
          ...user.organization,
          position: 'Director',
        },
      }
      
      console.log(updatedUser)
      

      Cela donnera le résultat :

      Output

      id: 3 name: "Ron" organization: {name: "Parks & Recreation", city: "Pawnee", position: "Director"}

      Spread avec appels de fonction

      Spread peut également être utilisé avec les arguments dans les appels de fonction.

      Par exemple, voici une fonction multiply qui prend trois paramètres et les multiplie.

      // Create a function to multiply three items
      function multiply(a, b, c) {
        return a * b * c
      }
      

      Normalement, vous feriez passer trois valeurs individuellement comme arguments à l’appel de fonction, comme ceci :

      multiply(1, 2, 3)
      

      Cela donnerait ce qui suit :

      Output

      6

      Cependant, si toutes les valeurs que vous voulez passer à la fonction existent déjà dans un tableau, la syntaxe de spread vous permet d’utiliser chaque élément d’un tableau comme argument :

      const numbers = [1, 2, 3]
      
      multiply(...numbers)
      

      Cela donnera le même résultat :

      Output

      6

      Note : Sans spread, ceci peut être réalisé en utilisant apply() :

      multiply.apply(null, [1, 2, 3])
      

      Il en résultera :

      Output

      6

      Maintenant que vous avez vu comment spread peut raccourcir votre code, vous pouvez vous pencher sur une utilisation différente de la syntaxe ... : les paramètres de rest.

      Les paramètres de Rest

      La dernière caractéristique que vous apprendrez dans cet article est la syntaxe des paramètres de rest. La syntaxe est la même que celle de spread (...) mais a l’effet inverse. Au lieu de décomposer un tableau ou un objet en valeurs individuelles, la syntaxe de rest va créer un tableau d’un nombre indéfini d’arguments.

      Dans la fonction restTest par exemple, si nous voulions qu’args soit un tableau composé d’un nombre indéfini d’arguments, on pourrait avoir ce qui suit : 

      function restTest(...args) {
        console.log(args)
      }
      
      restTest(1, 2, 3, 4, 5, 6)
      

      Tous les arguments transmis à la fonction restTest sont maintenant disponibles dans le tableau des args : 

      Output

      [1, 2, 3, 4, 5, 6]

      La syntaxe de Rest peut être utilisée comme seul paramètre ou comme dernier paramètre de la liste. S’il est utilisé comme seul paramètre, il rassemblera tous les arguments, mais s’il se trouve à la fin d’une liste, il rassemblera tous les arguments qui restent, comme on le voit dans cet exemple :

      function restTest(one, two, ...args) {
        console.log(one)
        console.log(two)
        console.log(args)
      }
      
      restTest(1, 2, 3, 4, 5, 6)
      

      Il s’agira de prendre les deux premiers arguments individuellement, puis de regrouper le reste dans un tableau :

      Output

      1 2 [3, 4, 5, 6]

      Dans l’ancien code, la variable arguments pouvait être utilisée pour rassembler tous les arguments transmis à une fonction :

      function testArguments() {
        console.log(arguments)
      }
      
      testArguments('how', 'many', 'arguments')
      

      Cela donnerait le résultat suivant :

      Output

      1Arguments(3) ["how", "many", "arguments"]

      Toutefois, cela présente quelques inconvénients. Premièrement, la variable arguments ne peut pas être utilisée avec les fonctions flèches.

      const testArguments = () => {
        console.log(arguments)
      }
      
      testArguments('how', 'many', 'arguments')
      

      Cela entraînerait une erreur :

      Output

      Uncaught ReferenceError: arguments is not defined

      En outre, arguments n’est pas un véritable tableau et ne peut pas utiliser des méthodes comme map et filter sans être préalablement converti en un tableau. Il recueillera également tous les arguments passés au lieu de se limiter au reste des arguments, comme on le voit dans l’exemple restTest (one, two, ...args).

      Rest peut également être utilisé lors de la déstructuration des tableaux :

      const [firstTool, ...rest] = ['hammer', 'screwdriver', 'wrench']
      
      console.log(firstTool)
      console.log(rest)
      

      Il en résultera :

      Output

      hammer ["screwdriver", "wrench"]

      Rest peut également être utilisé lors de la déstructuration d’objets :

      const { isLoggedIn, ...rest } = { id: 1, name: 'Ben', isLoggedIn: true }
      
      console.log(isLoggedIn)
      console.log(rest)
      

      En donnant le résultat suivant :

      Output

      true {id: 1, name: "Ben"}

      De cette façon, la syntaxe de rest fournit des méthodes efficaces pour rassembler une quantité indéterminée d’éléments.

      Conclusion

      Dans cet article, vous avez appris des choses sur la déstructuration, la syntaxe de spread et les paramètres de rest. En résumé :

      • La déstructuration est utilisée pour créer des variables à partir d’éléments de tableau ou de propriétés d’objets.
      • La syntaxe de spread est utilisée pour décompresser les itérables tels que les tableaux, les objets et les appels de fonction.
      • La syntaxe des paramètres de rest crée un tableau à partir d’un nombre indéfini de valeurs.

      La déstructuration, les paramètres de repos et la syntaxe de spread sont des fonctions utiles de JavaScript qui aident à maintenir votre code succinct et propre.

      Si vous souhaitez voir la déstructuration en action, consultez Comment personnaliser les éléments de React avec des props qui utilise cette syntaxe pour déstructurer les données et les transmettre à des composants frontaux personnalisés. Si vous souhaitez en savoir plus sur JavaScript, retournez à notre Page de la série Comment coder en JavaScript. 



      Source link

      Comprendre les paramètres par défaut dans JavaScript


      L’auteur a choisi le COVID-19 Relief Fund pour recevoir un don dans le cadre du programme Write for DOnations.

      Introduction

      Dans ECMAScript 2015, les paramètres de fonction par défaut ont été introduits au langage JavaScript. Celles-ci permettent aux développeurs d’initialiser une fonction avec des valeurs par défaut si les arguments ne sont pas fournis à l’appel de fonction. Initialiser les paramètres de fonction de cette manière rendra vos fonctions plus faciles à lire et moins sujettes aux erreurs, et fournira un comportement par défaut pour vos fonctions. Cela vous aidera à éviter les erreurs dues au passage d’arguments undefined et à la déstructuration d’objets qui n’existent pas.

      Dans cet article, vous examinerez la différence entre paramètres et arguments, vous apprendrez comment utiliser les paramètres par défaut dans les fonctions, vous verrez d’autres façons de prendre en charge les paramètres par défaut et vous apprendrez quels types de valeurs et d’expressions peuvent être utilisés comme paramètres par défaut. Vous passerez également en revue des exemples qui montrent comment les paramètres par défaut fonctionnent en JavaScript.

      Arguments et paramètres

      Avant d’expliquer les paramètres de fonction par défaut, il est important de savoir ce que sont les paramètres par défaut. Pour cette raison, nous allons d’abord examiner la différence entre les arguments et les paramètres d’une fonction.  Si vous souhaitez en savoir plus sur cette distinction, consultez notre article précédent de la série JavaScript, Comment définir les fonctions en JavaScript.

      Dans le bloc de code suivant, vous allez créer une fonction qui renvoie le cube d’un numéro donné, défini comme x :

      // Define a function to cube a number
      function cube(x) {
        return x * x * x
      }
      

      La variable x dans cet exemple est un paramètre — une variable nommée passée dans une fonction. Un paramètre doit toujours être contenu dans une variable et ne doit jamais avoir de valeur directe.

      Regardez maintenant ce prochain bloc de code, qui appelle la fonction cube que vous venez de créer :

      // Invoke cube function
      cube(10)
      

      Cela donnera le résultat suivant :

      Output

      1000

      Dans ce cas, 10 est un argument – une valeur transmise à une fonction lorsqu’elle est invoquée. Souvent, la valeur sera également contenue dans une variable comme dans cet exemple :

      // Assign a number to a variable
      const number = 10
      
      // Invoke cube function
      cube(number)
      

      Cela donnera le même résultat :

      Output

      1000

      Si vous ne passez pas un argument à une fonction qui en attend un, la fonction utilisera implicitement undefined en tant que valeur :

      // Invoke the cube function without passing an argument
      cube()
      

      Cela retournera :

      Output

      NaN

      Dans ce cas, cube() essaie de calculer la valeur de undefined * undefined * undefined, ce qui donne NaN, ou “not a number”. Pour en savoir plus, consultez la section sur les nombres de la rubrique “Comprendre les types de données en JavaScript”.

      Ce comportement automatique peut parfois poser problème. Dans certains cas, vous pouvez souhaiter que le paramètre ait une valeur même si aucun argument n’a été transmis à la fonction. C’est là que la fonction de paramètres par défaut est pratique, un sujet que vous aborderez dans la section suivante.

      Syntaxe des paramètres par défaut

      Avec l’ajout de paramètres par défaut dans ES2015, vous pouvez maintenant attribuer une valeur par défaut à n’importe quel paramètre, que la fonction utilisera au lieu d’undefined lorsqu’elle est appelée sans argument. Cette section vous montrera d’abord comment le faire manuellement, puis vous guidera dans la définition des paramètres par défaut.

      Sans paramètres par défaut, vous devriez explicitement rechercher des valeurs undefined afin de définir des valeurs par défaut, comme le montre cet exemple :

      // Check for undefined manually
      function cube(x) {
        if (typeof x === 'undefined') {
          x = 5
        }
      
        return x * x * x
      }
      
      cube()
      

      Cela utilise une instruction conditionnelle pour vérifier si la valeur a été automatiquement fournie comme undefined puis fixe la valeur de x à 5. Cela donnera la sortie suivante :

      Output

      125

      En revanche, l’utilisation de paramètres par défaut atteint le même but avec beaucoup moins de code. Vous pouvez définir une valeur par défaut pour le paramètre en cube en l’assignant avec l’opérateur d’assignation d’égalité (=), comme souligné ici :

      // Define a cube function with a default value
      function cube(x = 5) {
        return x * x * x
      }
      

      Maintenant, lorsque la fonction cube est invoquée sans argument, elle affectera 5 à x et retournera le calcul au lieu de NaN :

      // Invoke cube function without an argument
      cube()
      

      Output

      125

      Elle fonctionnera toujours comme prévu lorsqu’un argument est passé, en ignorant la valeur par défaut :

      // Invoke cube function with an argument
      cube(2)
      

      Output

      8

      Cependant, une mise en garde importante à noter est que la valeur par défaut du paramètre remplacera également une valeur explicite undefined passée comme argument à une fonction, comme démontré ici :

      // Invoke cube function with undefined
      cube(undefined)
      

      Cela donnera le calcul avec x égal à 5 :

      Output

      125

      Dans ce cas, les valeurs des paramètres par défaut ont été calculées, et une valeur undefined explicite ne les a pas remplacées.

      Maintenant que vous avez une idée de la syntaxe de base des paramètres par défaut, la section suivante indiquera comment les paramètres par défaut fonctionnent avec différents types de données.

      Types de données des paramètres par défaut

      Toute valeur ou objet primitif peut être utilisé comme valeur de paramètre par défaut.  Dans cette section, vous verrez comment cette flexibilité augmente les possibilités d’utilisation des paramètres par défaut.

      Tout d’abord, définissez des paramètres en utilisant un numéro, une chaîne, un booléen, un objet, un tableau et une valeur nulle comme valeur par défaut. Cet exemple utilisera la syntaxe des fonctions fléchées :

      // Create functions with a default value for each data type
      const defaultNumber = (number = 42) => console.log(number)
      const defaultString = (string = 'Shark') => console.log(string)
      const defaultBoolean = (boolean = true) => console.log(boolean)
      const defaultObject = (object = { id: 7 }) => console.log(object)
      const defaultArray = (array = [1, 2, 3]) => console.log(array)
      const defaultNull = (nullValue = null) => console.log(nullValue)
      

      Lorsque ces fonctions sont invoquées sans paramètres, elles utiliseront toutes les valeurs par défaut :

      // Invoke each function
      defaultNumber()
      defaultString()
      defaultBoolean()
      defaultObject()
      defaultArray()
      defaultNull()
      

      Output

      42 "Shark" true {id: 7} (3) [1, 2, 3] null

      Notez que tout objet créé dans un paramètre par défaut sera créé chaque fois que la fonction sera appelée. Un des cas d’utilisation courantes des paramètres par défaut est d’utiliser ce comportement pour obtenir des valeurs d’un objet. Si vous essayez de déstructurer ou d’accéder à une valeur à partir d’un objet qui n’existe pas, cela lancera une erreur. Cependant, si le paramètre par défaut est un objet vide, cela donnera simplement des valeurs undefined au lieu de lancer une erreur :

      // Define a settings function with a default object
      function settings(options = {}) {
        const { theme, debug } = options
      
        // Do something with settings
      }
      

      Cela permet d’éviter l’erreur causée par la déstructuration d’objets qui n’existent pas.

      Maintenant que vous avez vu comment les paramètres par défaut fonctionnent avec différents types de données, la section suivante indiquera comment plusieurs paramètres par défaut peuvent fonctionner ensemble.

      Utilisation de plusieurs paramètres par défaut

      Vous pouvez utiliser autant de paramètres par défaut que vous voulez dans une fonction. Cette section vous montrera comment procéder et comment l’utiliser pour manipuler le DOM dans un exemple concret.

      Tout d’abord, déclarez une fonction sum() avec plusieurs paramètres par défaut :

      // Define a function to add two values
      function sum(a = 1, b = 2) {
        return a + b
      }
      
      sum()
      

      Il en résultera le calcul par défaut suivant :

      Output

      3

      De plus, la valeur utilisée dans un paramètre peut être utilisée dans n’importe quel paramètre par défaut ultérieur, de gauche à droite. Par exemple, cette fonction createUser crée un objet userObj comme troisième paramètre, et tout ce que la fonction elle-même fait est de retourner userObj avec les deux premiers paramètres :

      // Define a function to create a user object using parameters
      function createUser(name, rank, userObj = { name, rank }) {
        return userObj
      }
      
      // Create user
      const user = createUser('Jean-Luc Picard', 'Captain')
      

      Si vous appelez user ici, vous obtiendrez ce qui suit :

      Output

      {name: "Jean-Luc Picard", rank: "Captain"}

      Il est généralement recommandé de placer tous les paramètres par défaut à la fin d’une liste de paramètres, afin de pouvoir facilement laisser de côté les valeurs facultatives. Si vous utilisez d’abord un paramètre par défaut, vous devrez explicitement passer undefined pour utiliser la valeur par défaut.

      Voici un exemple avec le paramètre par défaut au début de la liste :

      // Define a function with a default parameter at the start of the list
      function defaultFirst(a = 1, b) {
        return a + b
      }
      

      Lorsque vous appelez cette fonction, vous devriez appeler defaultFirst() avec deux arguments :

      defaultFirst(undefined, 2)
      

      Cela donnerait ce qui suit :

      Output

      3

      Voici un exemple avec le paramètre par défaut à la fin de la liste :

      // Define a function with a default parameter at the end of the list
      function defaultLast(a, b = 1) {
        return a + b
      }
      
      defaultLast(2)
      

      Cela donnerait la même valeur :

      Output

      3

      Les deux fonctions ont le même résultat, mais celle dont la valeur par défaut est la dernière permet un appel de fonction beaucoup plus propre.

      Pour un exemple concret, voici une fonction qui va créer un élément DOM, et ajouter un label texte et des classes, si elles existent.

      // Define function to create an element
      function createNewElement(tag, text, classNames = []) {
        const el = document.createElement(tag)
        el.textContent = text
      
        classNames.forEach(className => {
          el.classList.add(className)
        })
      
        return el
      }
      

      Vous pouvez appeler la fonction avec certaines classes dans un tableau :

      const greeting = createNewElement('p', 'Hello!', ['greeting', 'active'])
      

      L’appel de greeting donnera la valeur suivante :

      Output

      <p class="greeting active">Hello!</p>

      Cependant, si vous quittez le tableau de classNames hors de l’appel de fonction, cela fonctionne toujours.

      const greeting2 = createNewElement('p', 'Hello!')
      

      greatt2 a maintenant la valeur suivante :

      Output

      <p>Hello!</p>

      Dans cet exemple, forEach() peut être utilisé sur un tableau vide sans problème. Si ce tableau vide n’était pas défini dans le paramètre par défaut, vous obtiendriez l’erreur suivante :

      Output

      VM2673:5 Uncaught TypeError: Cannot read property 'forEach' of undefined at createNewElement (<anonymous>:5:14) at <anonymous>:12:18

      Maintenant que vous avez vu comment plusieurs paramètres par défaut peuvent interagir, vous pouvez passer à la section suivante pour voir comment les appels de fonction opèrent en tant que paramètres par défaut.

      Appels de fonction comme paramètres par défaut

      En plus des primitives et des objets, le résultat de l’appel d’une fonction peut être utilisé comme paramètre par défaut.

      Dans ce bloc de code, vous créerez une fonction pour renvoyer un nombre aléatoire, puis vous utiliserez le résultat comme valeur de paramètre par défaut dans une fonction cube :

      // Define a function to return a random number from 1 to 10
      function getRandomNumber() {
        return Math.floor(Math.random() * 10)
      }
      
      // Use the random number function as a default parameter for the cube function
      function cube(x = getRandomNumber()) {
        return x * x * x
      }
      

      Maintenant, l’invocation de la fonction cube sans paramètre aura des résultats potentiellement différents chaque fois que vous l’appelez :

      // Invoke cube function twice for two potentially different results
      cube()
      cube()
      

      Le résultat de ces appels de fonction variera :

      Output

      512 64

      Vous pouvez même utiliser des méthodes intégrées, comme celles de l’objet Math, et utiliser la valeur renvoyée dans un appel de fonction comme paramètre dans une autre fonction.

      Dans l’exemple suivant, un nombre aléatoire est attribué à x, qui est utilisé comme paramètre dans la fonction cube que vous avez créée.  Le paramètre y calculera alors la racine cubique du nombre et vérifiera si x et y sont égaux :

      // Assign a random number to x
      // Assign the cube root of the result of the cube function and x to y
      function doesXEqualY(x = getRandomNumber(), y = Math.cbrt(cube(x))) {
        return x === y
      }
      
      doesXEqualY()
      

      Cela donnera le résultat :

      Output

      true

      Un paramètre par défaut peut même être une définition de fonction, comme on le voit dans cet exemple, qui définit un paramètre comme la fonction inner et renvoie l’appel de fonction du paramètre :

      // Define a function with a default parameter that is an anonymous function
      function outer(
        parameter = function inner() {
          return 100
        }
      ) {
        return parameter()
      }
      
      // Invoke outer function
      outer()
      

      Output

      100

      Cette fonction inner sera créée à partir de zéro chaque fois que la fonction outer est invoquée.

      Conclusion

      Dans cet article, vous avez appris ce que sont les paramètres de fonction par défaut et comment les utiliser. Vous pouvez maintenant utiliser les paramètres par défaut pour vous aider à garder vos fonctions propres et faciles à lire. Vous pouvez également assigner des objets et des tableaux vides aux paramètres par défaut afin de réduire à la fois la complexité et les lignes de code lorsque vous traitez des situations telles que la récupération de valeurs d’un objet ou le bouclage dans un tableau.

      Si vous souhaitez en savoir plus sur JavaScript, consultez la page d’accueil de notre série Comment coder en JavaScript, ou parcourez notre série Comment coder en Node.js pour lire des articles sur le développement back-end.



      Source link

      Comprendre les objects Map et Set en JavaScript


      L’auteur a choisi le Open Internet/Free Speech Fund comme récipiendaire d’un don dans le cadre du programme Write for Donations.

      En JavaScript, les développeurs passent souvent beaucoup de temps à décider de la structure de données correcte à utiliser. En effet, le choix de la bonne structure de données peut faciliter la manipulation ultérieure de ces données, ce qui permet de gagner du temps et de rendre le code plus facile à comprendre. Les deux structures de données prédominantes pour le stockage des collections de données sont Objets et Tableaux (un type d’objet). Les développeurs utilisent des Objets pour stocker les paires clé/valeur et des Tableaux pour stocker les listes indexées. Toutefois, pour donner plus de flexibilité aux développeurs, la spécification ECMAScript 2015 a introduit deux nouveaux types d’objets itératifs : les objets Map, qui sont des collections ordonnées de paires clé/valeur, et les objets Set, qui sont des collections de valeurs uniques.

      Dans cet article, vous passerez en revue les objets Map et Set, ce qui les rend similaires ou différents des Objets et des Tableaux, les propriétés et méthodes dont ils disposent, et des exemples d’utilisations pratiques.

      Objets Map

      Un objet Map est une collection de paires clé/valeur qui peut utiliser n’importe quel type de données comme clé et peut maintenir l’ordre de ses entrées. Les objets Map comportent des éléments d’Objets (une collection unique de paires clé/valeur) et de Tableaux (une collection ordonnée), mais sont plus proches des Objets sur le plan conceptuel. En effet, bien que la taille et l’ordre des entrées soient préservés comme un Tableau, les entrées elles-mêmes sont des paires clé/valeur comme les Objets.

      Les objets Map peuvent être initialisés avec la nouvelle syntaxe Map() :

      const map = new Map()
      

      Cela nous donne un objet Map vide :

      Output

      Map(0) {}

      Ajout de valeurs à un objet Map

      Vous pouvez ajouter des valeurs à un objet Map avec la méthode set(). Le premier argument sera la clé, et le second la valeur.

      Ce qui suit ajoute trois paires clé/valeur à l’objet Map :

      map.set('firstName', 'Luke')
      map.set('lastName', 'Skywalker')
      map.set('occupation', 'Jedi Knight')
      

      Ici, nous commençons à voir comment les objets Map possèdent à la fois des éléments d’Objets et de Tableaux. Comme dans un Tableau, nous avons une collection indexée à zéro, et nous pouvons également voir combien d’éléments se trouvent par défaut dans l’objet Map. Les objets Map utilisent la syntaxe => pour signifier les paires clé/valeur en tant que key => value :

      Output

      Map(3) 0: {"firstName" => "Luke"} 1: {"lastName" => "Skywalker"} 2: {"occupation" => "Jedi Knight"}

      Cet exemple ressemble à un objet ordinaire avec des clés en chaîne, mais nous pouvons utiliser n’importe quel type de données comme clé avec des objets Map.

      Outre la définition manuelle de valeurs sur un objet Map, nous pouvons également initialiser un objet Map avec des valeurs existantes. Pour ce faire, nous utilisons un Tableau des Tableaux contenant deux éléments qui représentent chacun une paire clé/valeur ; ce tableau ressemble à ceci :

      [ [ 'key1', 'value1'], ['key2', 'value2'] ]
      

      En utilisant la syntaxe suivante, nous pouvons recréer le même objet Map :

      const map = new Map([
        ['firstName', 'Luke'],
        ['lastName', 'Skywalker'],
        ['occupation', 'Jedi Knight'],
      ])
      

      Remarque : cet exemple utilise des virgules de fin de ligne, également appelées “dangling commas”. Il s’agit d’une pratique de formatage JavaScript dans laquelle le dernier élément d’une série lors de la déclaration d’un ensemble de données comporte une virgule finale. Bien que ce choix de formatage puisse être utilisé pour des différences plus nettes et une manipulation plus facile du code, son utilisation ou non est une question de préférence. Pour plus d’informations sur les virgules de fin de ligne, consultez cet article sur les virgules de fin de ligne dans les documents web de MDN.

      Soit dit en passant, cette syntaxe est la même que celle qui résulte de l’appel de Object.entries() sur un Objet. Cela permet de convertir un Objet en un objet Map, comme le montre le bloc de code suivant :

      const luke = {
        firstName: 'Luke',
        lastName: 'Skywalker',
        occupation: 'Jedi Knight',
      }
      
      const map = new Map(Object.entries(luke))
      

      Vous pouvez également transformer un objet Map en un Objet ou un Tableau avec une seule ligne de code.

      Ce qui suit permet de convertir un objet Map en Objet :

      const obj = Object.fromEntries(map)
      

      Il en résultera la valeur suivante de obj :

      Output

      {firstName: "Luke", lastName: "Skywalker", occupation: "Jedi Knight"}

      Maintenant, convertissons un objet Map en Tableau :

      const arr = Array.from(map)
      

      Il en résultera le tableau suivant pour arr :

      Output

      [ ['firstName', 'Luke'], ['lastName', 'Skywalker'], ['occupation', 'Jedi Knight'] ]

      Clés d’objet Map

      Les objets Map acceptent tout type de données comme clé, et n’autorisent pas la duplication des valeurs de la clé. Nous pouvons le démontrer en créant un objet Map et en utilisant des valeurs non linéaires comme clés, ainsi qu’en attribuant deux valeurs à la même clé.

      Tout d’abord, initialisons une carte avec des clés non ordonnées :

      const map = new Map()
      
      map.set('1', 'String one')
      map.set(1, 'This will be overwritten')
      map.set(1, 'Number one')
      map.set(true, 'A Boolean')
      

      Cet exemple remplacera la première clé de 1 par la suivante, et traitera "1" la chaîne et 1 le chiffre comme des clés uniques :

      Output

      0: {"1" => "String one"} 1: {1 => "Number one"} 2: {true => "A Boolean"}

      Bien qu’il soit communément admis qu’un objet JavaScript ordinaire peut déjà traiter des nombres, des booléens et d’autres types de données primitives comme des clés, ce n’est en fait pas le cas, car les objets changent toutes les clés en chaînes de caractères.

      À titre d’exemple, initialisez un objet avec une clé numérique et comparez la valeur d’une clé numérique 1 et d’une clé "1" en chaîne :

      // Initialize an object with a numerical key
      const obj = { 1: 'One' }
      
      // The key is actually a string
      obj[1] === obj['1']  // true
      

      C’est pourquoi si vous essayez d’utiliser un objet comme clé, il imprimera la chaîne de caractères Objet à la place.

      Par exemple, créez un Objet et utilisez-le ensuite comme clé d’un autre Objet :

      // Create an object
      const objAsKey = { foo: 'bar' }
      
      // Use this object as the key of another object
      const obj = {
        [objAsKey]: 'What will happen?'
      }
      

      Il en résultera ce qui suit :

      Output

      {[object Object]: "What will happen?"}

      Ce n’est pas le cas avec un objet Map. Essayez de créer un Objet et de le définir comme la clé d’un objet Map :

      // Create an object
      const objAsKey = { foo: 'bar' }
      
      const map = new Map()
      
      // Set this object as the key of a Map
      map.set(objAsKey, 'What will happen?')
      

      La key de l’élément Map est maintenant l’objet que nous avons créé.

      Output

      key: {foo: "bar"} value: "What will happen?"

      Il y a une chose importante à noter concernant l’utilisation d’un Objet ou d’un Tableau comme clé : l’objet Map utilise la référence à l’Objet pour comparer l’égalité, et non la valeur littérale de l’Objet. En JavaScript {} === {} renvoie false (faux), car les deux Objets ne sont pas les mêmes deux Objets, bien qu’ayant la même valeur (vide).

      Cela signifie que l’ajout de deux Objets uniques ayant la même valeur créera un objet Map à deux entrées :

      // Add two unique but similar objects as keys to a Map
      map.set({}, 'One')
      map.set({}, 'Two')
      

      Il en résultera ce qui suit :

      Output

      Map(2) {{…} => "One", {…} => "Two"}

      Mais en utilisant deux fois la même référence d’Objet, on crée un objet Map avec une seule entrée.

      // Add the same exact object twice as keys to a Map
      const obj = {}
      
      map.set(obj, 'One')
      map.set(obj, 'Two')
      

      Ce qui donnera le résultat suivant :

      Output

      Map(1) {{…} => "Two"}

      Le second set() met à jour exactement la même clé que le premier, de sorte que nous nous retrouvons avec un objet Map qui n’a qu’une seule valeur.

      Ajout et suppression d’éléments d’un objet Map

      L’un des inconvénients du travail avec les Objets est qu’il peut être difficile de les énumérer, ou de travailler avec toutes les clés ou valeurs. La structure de l’objet Map, en revanche, possède de nombreuses propriétés intégrées qui rendent le travail avec leurs éléments plus direct.

      Nous pouvons initialiser un nouvel objet Map pour démontrer les méthodes et propriétés suivantes : delete(), has(), get(), et size.

      // Initialize a new Map
      const map = new Map([
        ['animal', 'otter'],
        ['shape', 'triangle'],
        ['city', 'New York'],
        ['country', 'Bulgaria'],
      ])
      

      Utilisez la méthode has() pour vérifier l’existence d’un élément dans un objet Map. has() renverra un booléen.

      // Check if a key exists in a Map
      map.has('shark') // false
      map.has('country') // true
      

      Utilisez la méthode get() pour récupérer une valeur par clé.

      // Get an item from a Map
      map.get('animal') // "otter"
      

      L’un des avantages particuliers des objets Map par rapport aux Objets est que vous pouvez trouver la taille d’un objet Map à tout moment, comme vous le feriez avec un Tableau. Vous pouvez obtenir le nombre d’articles dans un objet Map avec la propriété size. Cela implique moins d’étapes que la conversion d’un Objet en Tableau pour en déterminer la longueur.

      // Get the count of items in a Map
      map.size // 4
      

      Utilisez la méthode delete() pour supprimer un élément d’un objet Map par clé. La méthode retournera un booléen-true (vrai) si un élément existait et a été supprimé, et false (faux) s’il ne correspondait à aucun élément.

      // Delete an item from a Map by key
      map.delete('city') // true
      

      Il en résultera la carte suivante :

      Output

      Map(3) {"animal" => "otter", "shape" => "triangle", "country" => "Bulgaria"}

      Enfin, un objet Map peut être débarrassé de toutes ses valeurs avec map.clear().

      // Empty a Map
      map.clear()
      

      Il en résultera :

      Output

      Map(0) {}

      Clés, Valeurs et Entrées pour objets Map

      Les objets peuvent récupérer des clés, des valeurs et des entrées en utilisant les propriétés du constructeur d'Objet. Les objets Map, en revanche, disposent de méthodes prototypes qui nous permettent d’obtenir directement les clés, les valeurs et les entrées de l’instance de l’objet Map.

      Les méthodes keys(), values(), et entries() renvoient toutes un MapIterator, qui est similaire à un Tableau en ce sens que vous pouvez utiliser for...of pour boucler les valeurs.

      Voici un autre exemple d’objet Map, que nous pouvons utiliser pour démontrer ces méthodes :

      const map = new Map([
        [1970, 'bell bottoms'],
        [1980, 'leg warmers'],
        [1990, 'flannel'],
      ])
      

      La méthode keys() renvoie les clés :

      map.keys()
      

      Output

      MapIterator {1970, 1980, 1990}

      La méthode values() renvoie les valeurs :

      map.values()
      

      Output

      MapIterator {"bell bottoms", "leg warmers", "flannel"}

      La méthode entries() renvoie un tableau de paires clé/valeur :

      map.entries()
      

      Output

      MapIterator {1970 => "bell bottoms", 1980 => "leg warmers", 1990 => "flannel"}

      Itération avec objet Map

      Map dispose d’une méthode forEach intégrée, similaire à celle d’un Tableau, pour l’itération intégrée. Cependant, il y a une petite différence dans ce qu’ils répètent. Le rappel du forEach d’un objet Map se fait par la value, la key et l’objet Map lui-même, tandis que la version Tableau se fait par l’élément, l’index et le tableau lui-même.

      // Map
      Map.prototype.forEach((value, key, map) = () => {})
      
      // Array
      Array.prototype.forEach((item, index, array) = () => {})
      

      C’est un grand avantage pour les objets Map par rapport aux Objets, car les Objets doivent être convertis avec keys(), values() ou entries(), et il n’y a pas de moyen simple de récupérer les propriétés d’un Objet sans le convertir.

      Pour le démontrer, parcourons notre objet Map et enregistrons les paires clé/valeur sur la console :

      // Log the keys and values of the Map with forEach
      map.forEach((value, key) => {
        console.log(`${key}: ${value}`)
      })
      

      Il en résultera :

      Output

      1970: bell bottoms 1980: leg warmers 1990: flannel

      Comme une boucle for...of se réitère sur des itérables comme objet Map et Tableau, nous pouvons obtenir exactement le même résultat en déstructurant l’ensemble des éléments de l’objet Map :

      // Destructure the key and value out of the Map item
      for (const [key, value] of map) {
        // Log the keys and values of the Map with for...of
        console.log(`${key}: ${value}`)
      }
      

      Propriétés et méthodes Map

      Le tableau suivant présente une liste des propriétés et des méthodes Map pour une consultation rapide :

      Propriétés/Méthodes Description Retours
      set(key, value) Ajoute une paire clé/valeur à une carte Objet Map
      delete(key) Supprime une paire clé/valeur d’un objet Map par clé Booléen
      get(key) Retourne une valeur par clé valeur
      has(key) Recherche la présence d’un élément dans un objet Map par clé Booléen
      clear() Supprime tous les éléments d’un objet Map S/O
      keys() Retourne toutes les clés dans un objet Map Objet MapIterator
      values() Retourne toutes les valeurs dans un objet Map Objet MapIterator
      entries() Retourne toutes les clés et valeurs dans un objet Map sous forme de [key, valeur] Objet MapIterator
      forEach() Se réitère dans l’objet Map dans l’ordre d’insertion S/O
      size Retourne le nombre d’items dans un objet Map Number

      Quand utiliser Map

      En résumé, les objets Map sont similaires aux Objets dans la mesure où ils contiennent des paires clé/valeur, mais les objets Map présentent plusieurs avantages par rapport aux Objets :

      • Taille – Les objets Map ont une propriété size, alors que les Objets n’ont pas de moyen intégré pour récupérer leur taille.
      • Itération – Les objets Map sont directement itérables alors que les Objets ne le sont pas.
      • Flexibilité – Les objets Map peuvent avoir n’importe quel type de données (primitives ou Objets) comme clé pour une valeur, alors que les Objets ne peuvent avoir que des chaînes de caractères.
      • Ordonné – Les objets Map conservent leur ordre d’insertion, alors que les Objets n’ont pas d’ordre garanti.

      En raison de ces facteurs, les objets Map constituent une structure de données puissante à prendre en compte. Cependant, les Objets présentent également des avantages importants :

      • JSON – Les Objets fonctionnent parfaitement avec JSON.parse() et JSON.stringify(), deux fonctions essentielles pour travailler avec JSON, un format de données commun que de nombreuses REST API traitent.
      • Travailler avec un seul élément – En travaillant avec une valeur connue dans un Objet, vous pouvez y accéder directement avec la clé sans avoir besoin d’utiliser une méthode, telle que get() d’objet Map.

      Cette liste vous aidera à décider si un objet Map ou un Objet est la bonne structure de données pour votre cas d’utilisation.

      Objet Set

      Un objet Set est une collection de valeurs uniques. Contrairement à un objet Map, un objet Set est conceptuellement plus proche d’un Tableau que d’un Objet, puisqu’il s’agit d’une liste de valeurs et non de paires clé/valeur. Toutefois, l’objet Set ne remplace pas les Tableaux, mais constitue plutôt un complément pour fournir un soutien supplémentaire pour le travail avec des données dupliquées.

      Vous pouvez initialiser les objets Set avec la nouvelle syntaxe Set().

      const set = new Set()
      

      Cela nous donne un objet Set vide :

      Output

      Set(0) {}

      Les éléments peuvent être ajoutés à un objet Set avec la méthode add(). (À ne pas confondre avec la méthode set() disponible pour Map, bien qu’elles soient similaires).

      // Add items to a Set
      set.add('Beethoven')
      set.add('Mozart')
      set.add('Chopin')
      

      Comme les objets Set ne peuvent contenir que des valeurs uniques, toute tentative d’ajouter une valeur qui existe déjà sera ignorée.

      set.add('Chopin') // Set will still contain 3 unique values
      

      Note : la même comparaison d’égalité qui s’applique aux clés Map s’applique aux items Set. Deux objets qui ont la même valeur mais ne partagent pas la même référence ne seront pas considérés comme égaux.

      Vous pouvez également initialiser les objets Set avec un Tableau de valeurs. S’il y a des valeurs en double dans le tableau, elles seront supprimées de l’objet Set.

      // Initialize a Set from an Array
      const set = new Set(['Beethoven', 'Mozart', 'Chopin', 'Chopin'])
      

      Output

      Set(3) {"Beethoven", "Mozart", "Chopin"}

      Inversement, un objet Set peut être converti en un Tableau avec une ligne de code :

      const arr = [...set]
      

      Output

      (3) ["Beethoven", "Mozart", "Chopin"]

      Set possède un grand nombre de méthodes et de propriétés identiques à celles de Map, notamment delete(), has(), clear() et size.

      // Delete an item
      set.delete('Beethoven') // true
      
      // Check for the existence of an item
      set.has('Beethoven') // false
      
      // Clear a Set
      set.clear()
      
      // Check the size of a Set
      set.size // 0
      

      Notez que Set n’a pas de moyen d’accéder à une valeur par une clé ou un index, comme Map.get(key) ou arr[index].

      Clés, Valeurs et Entrées pour objets Set

      Map et Set ont tous deux des méthodes keys(), values(), et entries() qui renvoient un itérateur. Cependant, si chacune de ces méthodes a un but distinct dans Map, les objets Set n’ont pas de clés, et les clés sont donc un alias pour les valeurs. Cela signifie que keys() et values() renverront toutes deux le même itérateur, et que entries() renverra la valeur deux fois. Il est plus logique de n’utiliser que des values() avec Set, car les deux autres méthodes existent pour la cohérence et la compatibilité croisée avec Map.

      const set = new Set([1, 2, 3])
      // Get the values of a set
      set.values()
      

      Output

      SetIterator {1, 2, 3}

      Itération avec Set

      Comme Map, Set a une méthode intégrée forEach(). Comme les objets Set n’ont pas de clés, le premier et le second paramètre du rappel forEach() renvoient la même valeur, il n’y a donc pas de cas d’utilisation en dehors de la compatibilité avec Map. Les paramètres de forEach() sont (value, key, set).

      forEach() et for...of peuvent tous deux être utilisés sur Set. Tout d’abord, examinons l’itération forEach() :

      const set = new Set(['hi', 'hello', 'good day'])
      
      // Iterate a Set with forEach
      set.forEach((value) => console.log(value))
      

      Ensuite, nous pouvons écrire la version for...of :

      // Iterate a Set with for...of
      for (const value of set) {  
          console.log(value);
      }
      

      Ces deux stratégies donneront les résultats suivants :

      Output

      hi hello good day

      Propriétés et méthodes de Set

      Le tableau suivant présente une liste des propriétés et des méthodes de Set pour une consultation rapide :

      Propriétés/Méthodes Description Retours
      add(value) Ajoute un nouvel élément à un objet Set Objet Set
      delete(value) Supprime l’élément spécifié d’un objet Set Booléen
      has() Recherche la présence d’un item dans un objet Set Booléen
      clear() Supprime tous les éléments d’un objet Set S/O
      keys() Renvoie toutes les valeurs d’un objet Set (identique à values()) Objet SetIterator
      values() Renvoie toutes les valeurs d’un objet Set (identique à values() Objet SetIterator
      entries() Retourne toutes les valeurs d’un objet Set comme [value, value] Objet SetIterator
      forEach() Se réitère dans l’objet Set dans l’ordre d’insertion S/O
      size Retourne le nombre d’items de l’objet Set Number

      Quand utiliser Set

      Set est un complément utile à votre boîte à outils JavaScript, en particulier pour travailler avec des valeurs doubles dans les données.

      En une seule ligne, nous pouvons créer un nouveau Tableau sans valeurs doubles à partir d’un Tableau qui a des valeurs doubles.

      const uniqueArray = [ ...new Set([1, 1, 2, 2, 2, 3])] // (3) [1, 2, 3]
      

      Il en résultera :

      Output

      (3) [1, 2, 3]

      Set peut être utilisé pour trouver l’union, l’intersection et la différence entre deux ensembles de données. Toutefois, les Tableaux présentent un avantage significatif par rapport aux objets Set pour la manipulation supplémentaire des données en raison des méthodes sort(), map(), filter() et reduce(), ainsi que de la compatibilité directe avec les méthodes JSON.

      Conclusion

      Dans cet article, vous avez appris qu’un objet Map est une collection de paires de clés/valeurs ordonnées, et qu’un objet Set est une collection de valeurs uniques. Ces deux structures de données ajoutent des capacités supplémentaires à JavaScript et simplifient les tâches courantes telles que la recherche de la longueur d’une collection de paires clé/valeur et la suppression des éléments en double d’un ensemble de données, respectivement. D’autre part, les Objets et les Tableaux ont été traditionnellement utilisés pour le stockage et la manipulation de données en JavaScript, et sont directement compatibles avec JSON, ce qui continue à en faire les structures de données les plus essentielles, notamment pour travailler avec les REST API. Les objets Map et Set sont principalement utiles comme structures de données de soutien pour les Objets et les Tableaux.

      Si vous souhaitez en savoir plus sur JavaScript, consultez la page d’accueil de notre série Comment coder en JavaScript, ou parcourez notre série Comment coder en Node.js pour lire des articles sur le développement back-end.



      Source link