MDN’s new design is in Beta! A sneak peek: https://blog.mozilla.org/opendesign/mdns-new-design-beta/

L'opérateur de décomposition

La syntaxe de décomposition permet d'étendre une expression en lieu et place de plusieurs arguments (pour les appels de fonctions) ou de plusieurs éléments (pour les littéraux de tableaux).

Syntaxe

Pour l'utilisation de la décomposition dans les appels de fonction :

f(...objetIterable);

Pour les littéraux de tableaux :

[...objetIterable, 4, 5, 6]

Pour la décomposition :

[a, b, ...objetIterable] = [1, 2, 3, 4, 5];

Pour les littéraux objets (nouvelle fonctionnalité pour ECMAScript, actuellement en brouillon de niveau 3) :

let objClone = { ...obj };

Exemples

Utiliser la décomposition dans les appels de fonction

Améliorer la fonction apply

Il arrive souvent qu'on veuille utiliser Function.prototype.apply avec un tableau parmi les arguments de la fonction utilisée :

function f(x, y, z) { }
var args = [0, 1, 2];
f.apply(null, args);

avec la décomposition, on peut désormais écrire :

function f(x, y, z) { }
var args = [0, 1, 2];
f(...args);

Tout argument passé à une fonction peut être décomposé grâce à l'opérateur et l'opérateur peut être utilisé pour plusieurs arguments.

function f(v, w, x, y, z) { }
var args = [0, 1];
f(-1, ...args, 2, ...[3]);

Utiliser apply avec l'opérateur new

Avec ES5, il n'est pas possible d'utiliser new avec apply (selon ES5 apply effectue un appel [[Call]] et pas un appel [[Construct]]). Avec ES2015, la syntaxe de décomposition permet de le faire naturellement :

var champsDate = lireChampsDate(maBaseDeDonnées);
var d = new Date(...champsDate);

Afin d'utiliser new avec un tableau de paramètres, sans utiliser la décomposition, il faudrait l'employer indirectement grâce à une application partielle :

function applyAndNew(constructor, args) {
   function partial () {
      return constructor.apply(this, args);
   };
   if (typeof constructor.prototype === "object") {
      partial.prototype = Object.create(constructor.prototype);
   }
   return partial;
}


function monConstructeur () {
   console.log("arguments.length: " + arguments.length);
   console.log(arguments);
   this.prop1="val1";
   this.prop2="val2";
};

var mesArguments = ["bi", "bop", "bup", null];
var monConstructeurAvecArguments = applyAndNew(monConstructor, mesArguments);

console.log(new monConstructeurAvecArguments);
// (log fourni par monConstructeur):           arguments.length: 4
// (log fourni par monConstructeur):           ["bi", "bop", "bup", null]
// (log fourni par "new monConstructeurAvecArguments"): {prop1: "val1", prop2: "val2"}

Améliorer la fonction push

push est souvent utilisé pour ajouter un tableau à la fin d'un autre tableau. Avec ES5, on peut utiliser le code suivant :

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
// On ajoute tous les éléments de arr2 à la fin de arr1
Array.prototype.push.apply(arr1, arr2);

Avec ES2015 et la décomposition, on peut utiliser :

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1.push(...arr2);

Utiliser la décomposition dans les littéraux de tableau

Améliorer les littéraux de tableau

À l'heure actuelle, sans la décomposition, si on a un tableau et qu'on souhaite créer un nouveau tableau composé du premier, on ne peut pas utiliser un littéral de tableau et il faut utiliser des fonctions comme push, splice, concat, etc. Avec la syntaxe de décomposition, cela devient plus succinct :

var articulations = ['épaules', 'genoux'];
var corps = ['têtes', ...articulations, 'bras', 'pieds'];
// ["têtes", "épaules", "genoux", "bras", "pieds"]

Comme pour les fonctions, l'opérateur peut être utilisé plusieurs fois.

Copier un tableau

var arr = [1, 2, 3];
var arr2 = [...arr];
arr2.push(4);

console.log(arr2); // [1, 2, 3, 4]
console.log(arr);  // [1, 2, 3] (inchangé)

Note : Lorsqu'on utilise la décomposition pour copier un tableau, celle-ci ne s'applique qu'au premier niveau de profondeur. Autrement dit, lorsqu'on utilise des tableaux à plusieurs dimensions (des tableaux imbriqués dans d'autres tableaux), il faut faire attention aux résultats. Il en va de même avec Object.assign() et avec la décomposition.

var a = [[1], [2], [3]];
var b = [...a]; // b vaut [[1], [2], [3]]

b.shift().shift(); // *a* vaut désormais [[], [2], [3]];

Une meilleure façon de concaténer des tableaux

concat est souvent utilisé afin de concaténer un tableau à la suite d'une autre. Avec ES5, on aurait le code suivant :

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
// On ajoute les éléments de arr2 après ceux de arr1
var nouveauTableau = arr1.concat(arr2);

Avec ES2015 et la décomposition, on peut écrire :

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1 = [...arr1, ...arr2];

unshift est souvent utilisé afin d'insérer des valeurs d'un tableau au début d'un autre tableau. Avec ES5, on peut écrire :

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
// On ajoute tous les éléments
// de arr2 au début de arr1
Array.prototype.unshift.apply(arr1, arr2) // arr1 vaut [3, 4, 5, 0, 1, 2]

Avec ES2015 et la décomposition, on peut écrire :

var arr1 = [4, 5, 6];
var arr2 = [1, 2, 3];
arr1 = [...arr2, ...arr1];
// arr1 vaut désormais [1, 2, 3, 4, 5, 6]

Utiliser la décomposition avec les littéraux objet

La proposition relative à la décomposition des propriétés (actuellement au stade de brouillon de niveau 3) vise à ajouter la décomposition des propriétés pour les littéraux objets. Cela permet de copier les propriétés énumérables directement rattachées à un objet source sur un nouvel objet.

Le clonage superficiel (qui ne rattache pas le prototype) ou la fusion d'objets peut donc être obtenue avec une syntaxe plus concise que celle utilisant Object.assign().

var obj1 = { toto: 'truc', x: 42 };
var obj2 = { toto: 'bidule', y: 13 };

var clone = { ...obj1 };
// Object { toto: 'truc', x: 42 }

var fusion = { ...obj1, ...obj2 };
// Object { toto: 'bidule', x: 42, y: 13 };

On notera que Object.assign() déclenche les mutateurs, ce qui n'est pas le cas pour l'opérateur de décomposition.

La décomposition ne s'applique qu'aux itérables

Pour rappel : l'opération de décomposition ne s'applique qu'aux objets itérables :

var obj = {"clé1" : "valeur1"};
function maFonction(x) {
  console.log(x); // undefined
}
maFonction(...obj);
var args = [...obj];
console.log(args, args.length) //[] 0

Spécifications

Spécification État Commentaires
ECMAScript 2015 (6th Edition, ECMA-262) Standard Défini dans plusieurs sections de la spécification : initialisateur de tableau, listes d'argument
ECMAScript Latest Draft (ECMA-262) Projet Aucune modification.
Décomposition des propriétés pour ECMAScript Brouillon Brouillon de niveau 3

Compatibilité des navigateurs

Fonctionnalité Chrome Firefox (Gecko) Edge Internet Explorer Opera Safari (WebKit)
Opérateur de décomposition dans les littéraux de tableaux 46 16 (16) Unknown (10240) Pas de support 37 7.1
Opérateur de décomposition dans les appels de fonctions 46 27 (27) Unknown (10240) Pas de support 37 7.1
Opérateur de décomposition pour la déstructuration 49 34 (34) Pas de support Pas de support 37 ?
Décomposition pour les littéraux objets 60 55 (55) Pas de support Pas de support Pas de support Pas de support
Fonctionnalité Android Webview Android Firefox Mobile (Gecko) Edge IE Mobile Opera Mobile Safari Mobile Chrome pour Android
Opérateur de décomposition dans les littéraux de tableaux Pas de support 46 16.0 (16) ? Pas de support Pas de support 8 46
Opérateur de décomposition dans les appels de fonctions Pas de support 46 27.0 (27) ? Pas de support Pas de support 8 46
Opérateur de décomposition pour la déstructuration Pas de support Pas de support 34 (34) ? ? ? ? Pas de support
Décomposition pour les littéraux objets Pas de support Pas de support 55.0 (55) Pas de support Pas de support Pas de support Pas de support  

Voir aussi

Étiquettes et contributeurs liés au document

 Contributeurs à cette page : SphinxKnight, Aminelahlou
 Dernière mise à jour par : SphinxKnight,