[ Web Proxy ]
URL:
Viewing: https://fr.javascript.info/destructuring-assignment [Back]  [Original]

L'affectation par dcomposition
FR

Nous souhaitons rendre ce projet open source disponible pour les gens du monde entier.

Aidez-nous traduire le contenu de ce tutoriel dans votre langue!

    Rechercher sur Javascript.info:
    Rechercher dans le tutoriel:
    Light themeDark theme
    DanskEnglishEspaolFranaisIndonesiaItalianoTrkeOzbek

    L'affectation par dcomposition

    Les deux structures de donnes les plus utilises en JavaScript sont Object et Array.

    • Les objets nous permettent de crer une seule entit qui stocke les lments de donnes par cl.
    • Les tableaux nous permettent de rassembler des lments de donnes dans une liste ordonne.

    Mais lorsque nous transmettons ceux-ci une fonction, il se peut que celle-ci nait pas besoin dun objet / tableau dans son ensemble, mais plutt de morceaux individuels.

    Laffectation par dcomposition est une syntaxe spciale qui nous permet de dcompresser des tableaux ou des objets dans un ensemble de variables, ce qui est parfois plus pratique.

    La dcomposition fonctionne galement trs bien avec des fonctions complexes comportant de nombreux paramtres, valeurs par dfaut, etc.

    Dcomposition dun tableau

    Voici un exemple de la faon dont un tableau est dcompos en variables :

    // nous avons un tableau avec le prnom et le nom
    let arr = ["John", "Smith"]
    
    // l'affectation par dcomposition
    // sets firstName = arr[0]
    // and surname = arr[1]
    let [firstName, surname] = arr;
    
    alert(firstName); // John
    alert(surname);  // Smith

    Maintenant, nous pouvons travailler avec des variables plutt que des parties du tableau.

    Cela a lair pas mal quand cest combin avec split ou tout autre mthode de renvoi de tableau :

    let [firstName, surname] = "John Smith".split(' ');
    alert(firstName); // John
    alert(surname);  // Smith

    Comme vous pouvez le voir, la syntaxe est simple. Il y a cependant plusieurs dtails particuliers. Voyons plus dexemples, pour mieux le comprendre.

    Dcomposition ne veut pas dire destruction.

    Cette manipulation est appele affectation par dcomposition, car elle se dcompose en copiant ses lments dans des variables. Mais le tableau lui-mme nest pas modifi.

    Cest juste une faon plus courte dcrire :

    // let [firstName, surname] = arr;
    let firstName = arr[0];
    let surname = arr[1];
    Ignorer les lments en utilisant des virgules

    Les lments indsirables du tableau peuvent galement tre supprims via une virgule supplmentaire :

    // second element is not needed
    let [firstName, , title] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];
    
    alert( title ); // Consul

    Dans le code ci-dessus, le deuxime lment du tableau est ignor, le troisime est attribu title et le reste du tableau est galement ignor (car il ny a pas de variables pour eux).

    Fonctionne avec nimporte quel itrable droite

    En fait, nous pouvons lutiliser avec nimporte quel itrable, pas seulement les tableaux :

    let [a, b, c] = "abc"; // ["a", "b", "c"]
    let [one, two, three] = new Set([1, 2, 3]);

    That works, because internally a destructuring assignment works by iterating over the right value. Its a kind of syntax sugar for calling for..of over the value to the right of = and assigning the values.

    Attribuer nimporte quoi la partie gauche

    Nous pouvons utiliser nimporte quels assignables gauche.

    Par exemple, une proprit dobjet :

    let user = {};
    [user.name, user.surname] = "John Smith".split(' ');
    
    alert(user.name); // John
    alert(user.surname); // Smith
    Boucler avec .entries()

    Dans le chapitre prcdent, nous avons vu la mthode Object.entries(obj).

    Nous pouvons lutiliser avec la dcomposition pour boucler sur les cls et valeurs dun objet :

    let user = {
      name: "John",
      age: 30
    };
    
    // boucler sur les cls et les valeurs
    for (let [key, value] of Object.entries(user)) {
      alert(`${key}:${value}`); // name:John, ensuite age:30
    }

    Le code similaire pour un Map est plus simple, car il est itrable :

    let user = new Map();
    user.set("name", "John");
    user.set("age", "30");
    
    // Map est itr sous forme de paires [key, value], ce qui est trs pratique pour la dstructuration
    for (let [key, value] of user) {
      alert(`${key}:${value}`); // name:John, ensuite age:30
    }
    Astuce dchange de variables

    Il existe une astuce bien connue pour permuter les valeurs de deux variables laide dune affectation de dstructuration :

    let guest = "Jane";
    let admin = "Pete";
    
    // Permutons les valeurs : guest=Pete, admin=Jane
    [guest, admin] = [admin, guest];
    
    alert(`${guest} ${admin}`); // Pete Jane (chang avec succs !)

    Ici, nous crons un tableau temporaire de deux variables et le dstructurons immdiatement dans lordre permut.

    Nous pouvons changer plus de deux variables de cette faon.

    Le rest

    Habituellement, si le tableau est plus long que la liste gauche, les lments supplmentaires sont omis.

    Par exemple, ici, seuls deux lments sont pris et le reste est simplement ignor :

    let [name1, name2] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];
    
    alert(name1); // Julius
    alert(name2); // Caesar
    // Les autres lments ne sont affects nulle part

    Si nous souhaitons galement rassembler tout ce qui suit, nous pouvons ajouter un paramtre supplmentaire qui permet dobtenir le reste laide de trois points "..." :

    let [name1, name2, ...rest] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];
    
    // reste est un tableau d'lments,  partir du 3me
    alert(rest[0]); // Consul
    alert(rest[1]); // of the Roman Republic
    alert(rest.length); // 2

    La valeur de rest est le tableau des lments du tableau restants.

    Nous pouvons utiliser nimporte quel autre nom de variable la place de rest, assurez-vous simplement quil a trois points devant lui et soit plac en dernier dans laffectation par dcomposition.

    let [name1, name2, ...titles] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];
    // maintenant titles = ["Consul", "of the Roman Republic"]

    Les valeurs par dfaut

    Si le tableau est plus court que la liste des variables gauche, il ny aura aucune erreur. Les valeurs absentes sont considres comme non dfinies :

    let [firstName, surname] = [];
    
    alert(firstName); // undefined
    alert(surname); // undefined

    Si nous voulons quune valeur par dfaut remplace la valeur manquante, nous pouvons la fournir en utilisant = :

    // les valeurs par dfaut
    let [name = "Guest", surname = "Anonymous"] = ["Julius"];
    
    alert(name);    // Julius (depuis le tableau)
    alert(surname); // Anonymous (valeur par dfaut)

    Les valeurs par dfaut peuvent tre des expressions plus complexes ou mme des appels de fonction. Ils ne sont valus que si la valeur nest pas fournie.

    Par exemple, nous utilisons ici la fonction prompt pour deux valeurs par dfaut :

    // ne demande que le nom de famille
    let [name = prompt('name?'), surname = prompt('surname?')] = ["Julius"];
    
    alert(name);    // Julius (depuis le tableau)
    alert(surname); // saisi par l'utilisateur

    Notez que le prompt ne sexcutera que pour la valeur manquante (surname).

    Dcomposition dobject

    Laffectation par dcomposition fonctionne galement avec les objets.

    La syntaxe de base est la suivante :

    let {var1, var2} = {var1:, var2:}

    Nous devrions avoir un objet existant sur le ct droit, que nous voulons diviser en variables. La partie gauche contient un modle de type objet pour les proprits correspondantes. Dans le cas le plus simple, cest une liste de noms de variables dans {...}.

    Par exemple :

    let options = {
      title: "Menu",
      width: 100,
      height: 200
    };
    
    let {title, width, height} = options;
    
    alert(title);  // Menu
    alert(width);  // 100
    alert(height); // 200

    Les proprits options.title, options.width et options.height sont affectes aux variables correspondantes.

    Lordre na pas dimportance. Cela fonctionne aussi :

    // chang l'ordre dans let {...}
    let {height, width, title} = { title: "Menu", height: 200, width: 100 }

    Le pattern gauche peut tre plus complexe et spcifier le mapping entre proprits et variables.

    Si nous voulons affecter une proprit une variable portant un autre nom, par exemple, options.width pour aller dans la variable nomme w, alors nous pouvons la dfinir en utilisant deux points :

    let options = {
      title: "Menu",
      width: 100,
      height: 200
    };
    
    // { sourceProperty: targetVariable }
    let {width: w, height: h, title} = options;
    
    // width -> w
    // height -> h
    // title -> title
    
    alert(title);  // Menu
    alert(w);      // 100
    alert(h);      // 200

    Les deux points montrent quoi: va o. Dans lexemple ci-dessus, la proprit width est dfinie sur w, la proprit height est dfinie sur h et le title est attribu au mme nom.

    Pour les proprits potentiellement manquantes, nous pouvons dfinir les valeurs par dfaut laide de "=", comme ceci :

    let options = {
      title: "Menu"
    };
    
    let {width = 100, height = 200, title} = options;
    
    alert(title);  // Menu
    alert(width);  // 100
    alert(height); // 200

    Comme pour les tableaux ou les paramtres de fonction, les valeurs par dfaut peuvent tre des expressions ou mme des appels de fonction. Elles seront values si la valeur nest pas fournie.

    Le code prompt ci-dessous demande la width, mais pas le title.

    let options = {
      title: "Menu"
    };
    
    let {width = prompt("width?"), title = prompt("title?")} = options;
    
    alert(title);  // Menu
    alert(width);  // saisi par l'utilisateur

    Nous pouvons galement combiner les deux points et lgalit :

    let options = {
      title: "Menu"
    };
    
    let {width: w = 100, height: h = 200, title} = options;
    
    alert(title);  // Menu
    alert(w);      // 100
    alert(h);      // 200

    Si nous avons un objet complexe avec de nombreuses proprits, nous pouvons extraire que ce dont nous avons besoin :

    let options = {
      title: "Menu",
      width: 100,
      height: 200
    };
    
    // extraire uniquement le titre en tant que variable
    let { title } = options;
    
    alert(title); // Menu

    Le pattern rest

    Et si lobjet a plus de proprits que de variables ? Peut-on en prendre puis assigner le rest quelque part ?

    Nous pouvons utiliser le modle rest, comme nous lavons fait avec les tableaux. Il nest pas pris en charge par certains navigateurs plus anciens (IE, utilisez Babel pour le polyfiller), mais fonctionne avec les modernes.

    Cela ressemble ceci :

    let options = {
      title: "Menu",
      height: 200,
      width: 100
    };
    
    // title = proprit nomme title
    // rest = objet avec le reste des proprits
    let {title, ...rest} = options;
    
    // maintenant title="Menu", rest={height: 200, width: 100}
    alert(rest.height);  // 200
    alert(rest.width);   // 100
    Attention, sans let, a coince

    Dans les exemples ci-dessus, les variables ont t dclares juste avant laffectation : let {} = {}. Bien sr, nous pourrions aussi utiliser des variables existantes. Mais il y a un problme.

    Cela ne fonctionnera pas :

    let title, width, height;
    
    // erreur dans cette ligne
    {title, width, height} = {title: "Menu", width: 200, height: 100};

    Le problme est que JavaScript traite {...} dans le flux de code principal (pas dans une autre expression) en tant que bloc de code. De tels blocs de code peuvent tre utiliss pour regrouper des instructions, comme ceci :

    {
      // un bloc de code
      let message = "Hello";
      // ...
      alert( message );
    }

    Donc ici, JavaScript suppose que nous avons un bloc de code, cest pourquoi il y a une erreur. Nous voulons plutt la dstructuration.

    Pour montrer JavaScript quil ne sagit pas dun bloc de code, nous pouvons envelopper lexpression entre parenthses (...) :

    let title, width, height;
    
    // maintenant c'est bon
    ({title, width, height} = {title: "Menu", width: 200, height: 100});
    
    alert( title ); // Menu

    Dcomposition imbrique

    Si un objet ou un tableau contient dautres objets et tableaux imbriqus, nous pouvons utiliser des modles gauche plus complexes pour extraire des parties plus profondes.

    Dans le code ci-dessous, options a un autre objet dans la proprit size et un tableau dans la proprit items. Le modle gauche de laffectation a la mme structure pour en extraire des valeurs :

    let options = {
      size: {
        width: 100,
        height: 200
      },
      items: ["Cake", "Donut"],
      extra: true
    };
    
    // affectation par dcomposition divise sur plusieurs lignes pour la clart
    let {
      size: { // mettre la taille ici
        width,
        height
      },
      items: [item1, item2], // attribuer des lments ici
      title = "Menu" // non prsent dans l'objet (la valeur par dfaut est utilise)
    } = options;
    
    alert(title);  // Menu
    alert(width);  // 100
    alert(height); // 200
    alert(item1);  // Cake
    alert(item2);  // Donut

    Toutes les proprits de lobjet options, lexception de extra qui est absente dans la partie gauche, sont affects aux variables correspondantes :

    []

    Finnalement nous avons width, height, item1, item2 et title partir de la valeur par dfaut.

    Notez quil ny a pas de variables pour size et items, car nous prenons leur contenu la place.

    Paramtres de fonction intelligente

    Il peut arriver quune fonction ait plusieurs paramtres, dont la plupart sont facultatifs. Cest particulirement vrai pour les interfaces utilisateur. Imaginez une fonction qui cre un menu. Il peut avoir une largeur, une hauteur, un titre, une liste darticles, etc.

    Voici une mauvaise faon dcrire ce genre de fonction :

    function showMenu(title = "Untitled", width = 200, height = 100, items = []) {
      // ...
    }

    Dans la vraie vie, le problme est de savoir comment retenir lordre des arguments. Habituellement, les IDE essaient de nous aider, surtout si le code est bien document, mais quand mme Un autre problme est de savoir comment appeler une fonction lorsque la plupart des paramtres sont corrects par dfaut.

    Comme ceci ?

    // undefined o les valeurs par dfaut sont adquates
    showMenu("My Menu", undefined, undefined, ["Item1", "Item2"])

    Cest moche. Et devient illisible lorsque nous traitons plus de paramtres.

    La dcomposition vient la rescousse !

    Nous pouvons passer des paramtres sous forme dobjet, et la fonction les dcomposent immdiatement en variables :

    // on passe un objet  fonction
    let options = {
      title: "My menu",
      items: ["Item1", "Item2"]
    };
    
    // ...et il est immdiatement tendu aux variables
    function showMenu({title = "Untitled", width = 200, height = 100, items = []}) {
      // title, items  pris des options,
      // width, height  dfauts utiliss
      alert( `${title} ${width} ${height}` ); // My Menu 200 100
      alert( items ); // Item1, Item2
    }
    
    showMenu(options);

    Nous pouvons galement utiliser une dcomposition plus complexe avec des objets imbriqus et des mappings de deux points :

    let options = {
      title: "My menu",
      items: ["Item1", "Item2"]
    };
    
    function showMenu({
      title = "Untitled",
      width: w = 100,  // width va  w
      height: h = 200, // height va  h
      items: [item1, item2] // items premier lment va  item1, deuxime  item2
    }) {
      alert( `${title} ${w} ${h}` ); // My Menu 100 200
      alert( item1 ); // Item1
      alert( item2 ); // Item2
    }
    
    showMenu(options);

    La syntaxe complte est la mme que pour une affectation par dcomposition :

    function({
      incomingProperty: varName = defaultValue
      ...
    })

    Ensuite, pour un objet de paramtres, il y aura une variable varName pour la proprit incomingProperty, avec defaultValue par dfaut.

    Veuillez noter quune telle dstructuration suppose que showMenu() a un argument. Si nous voulons toutes les valeurs par dfaut, alors nous devrions spcifier un objet vide :

    showMenu({}); // ok, toutes les valeurs par dfaut
    
    showMenu(); // cela donnerait une erreur

    Nous pouvons rsoudre ce problme en faisant de {} la valeur par dfaut pour lobjet entier de paramtres :

    function showMenu({ title = "Menu", width = 100, height = 200 } = {}) {
      alert( `${title} ${width} ${height}` );
    }
    
    showMenu(); // Menu 100 200

    Dans le code ci-dessus, la totalit des arguments objet est {} par dfaut, il y a donc toujours quelque chose dcomposer.

    Rsum

    • Laffectation par dcomposition permet de mapper instantanment un objet ou un tableau sur de nombreuses variables.

    • La syntaxe complte de lobjet :

      let {prop : varName = default, ...rest} = object

      Cela signifie que la proprit prop doit aller dans la variable varName et que, si aucune proprit de ce type nexiste, la valeur default doit tre utilise.

      Les proprits dobjet sans mappage sont copies dans lobjet rest.

    • La syntaxe complte du tableau :

      let [item1 = default, item2, ...rest] = array

      Le premier item va item1; le second passe item2, tout le reste du tableau correspond au rest.

    • Il est possible dextraire des donnes de tableaux / objets imbriqus, pour cela le ct gauche doit avoir la mme structure que le droit.

    Exercices

    importance: 5

    Nous avons un objet :

    let user = {
      name: "John",
      years: 30
    };

    crivez laffectation par dcomposition qui se lit comme suit :

    • La proprit name dans la variable name.
    • La proprit years dans la variable age.
    • La proprit isAdmin dans la variable isAdmin (false si absent)

    Voici un exemple des valeurs aprs votre affectation :

    let user = { name: "John", years: 30 };
    
    // votre code  gauche ::
    // ... = user
    
    alert( name ); // John
    alert( age ); // 30
    alert( isAdmin ); // false
    solution
    let user = {
      name: "John",
      years: 30
    };
    
    let {name, years: age, isAdmin = false} = user;
    
    alert( name ); // John
    alert( age ); // 30
    alert( isAdmin ); // false
    importance: 5

    Il y a un objet salaries :

    let salaries = {
      "John": 100,
      "Pete": 300,
      "Mary": 250
    };

    Crer la fonction topSalary(salaries) qui renvoie le nom de la personne la mieux paye.

    • Si salaries est vide, devrait retourner null.
    • Sil y a plusieurs personnes les mieux payes, renvoyez-en une.

    P.S. Utilisez Object.entries et la dcomposition pour parcourir les paires cl / valeur.

    Open a sandbox with tests.

    solution
    function topSalary(salaries) {
    
      let maxSalary = 0;
      let maxName = null;
    
      for(const [name, salary] of Object.entries(salaries)) {
        if (maxSalary < salary) {
          maxSalary = salary;
          maxName = name;
        }
      }
    
      return maxName;
    }

    Ouvrez la solution avec des tests dans une sandbox.

    Carte du tutoriel

    Commentaires

    lire ceci avant de commenter
    • Si vous avez des amliorations suggrer, merci de soumettre une issue GitHub ou une pull request au lieu de commenter.
    • Si vous ne comprenez pas quelque chose dans l'article, merci de prciser.
    • Pour insrer quelques bouts de code, utilisez la balise <code>, pour plusieurs lignes enveloppez-les avec la balise <pre>, pour plus de 10 lignes - utilisez une sandbox (plnkr, jsbin, codepen)

    Web Proxy Viewer  |  New URL  |  Original Page