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.
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];
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).
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.
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
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
}
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
let, a coinceDans 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} = objectCela signifie que la proprit
propdoit aller dans la variablevarNameet que, si aucune proprit de ce type nexiste, la valeurdefaultdoit tre utilise.Les proprits dobjet sans mappage sont copies dans lobjet
rest. -
La syntaxe complte du tableau :
let [item1 = default, item2, ...rest] = arrayLe premier item va
item1; le second passeitem2, tout le reste du tableau correspond aurest. -
Il est possible dextraire des donnes de tableaux / objets imbriqus, pour cela le ct gauche doit avoir la mme structure que le droit.
Commentaires
<code>, pour plusieurs lignes enveloppez-les avec la balise<pre>, pour plus de 10 lignes - utilisez une sandbox (plnkr, jsbin, codepen)