Avancé20 min de lecture

Opérateurs Spread & Rest

Maîtrise la syntaxe ... pour décomposer des tableaux et objets, et collecter des arguments de fonction avec les paramètres rest.

L'opérateur Spread (...)

L'opérateur spread (...) décompose un itérable (comme un tableau ou un objet) en éléments individuels. Il ressemble à l'opérateur rest mais fonctionne dans le sens opposé.

Spread dans les tableaux — concaténer ou copier des tableaux :

javascript
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];

const merged = [...arr1, ...arr2];
console.log(merged); // [1, 2, 3, 4, 5, 6]

const copy = [...arr1];
console.log(copy);   // [1, 2, 3] (un nouveau tableau, pas une référence)

Spread dans les appels de fonction — passer les éléments d'un tableau comme arguments individuels :

javascript
const numbers = [5, 2, 8, 1, 9];
console.log(Math.max(...numbers)); // 9

// Sans spread, tu aurais besoin de :
console.log(Math.max.apply(null, numbers)); // 9 (ancienne méthode)

Spread dans les littéraux d'objet — fusionner ou copier des objets :

javascript
const defaults = { theme: 'light', lang: 'en' };
const userPrefs = { theme: 'dark', fontSize: 16 };

const settings = { ...defaults, ...userPrefs };
console.log(settings);
// { theme: 'dark', lang: 'en', fontSize: 16 }

Quand les propriétés se chevauchent, les valeurs ultérieures écrasent les précédentes. Cela rend spread parfait pour appliquer des surcharges aux paramètres par défaut.

L'opérateur Rest (...)

L'opérateur rest utilise aussi ... mais fait l'inverse — il collecte plusieurs éléments dans un seul tableau.

Rest dans les paramètres de fonction — accepter un nombre quelconque d'arguments :

javascript
function sum(...numbers) {
  return numbers.reduce((total, n) => total + n, 0);
}

console.log(sum(1, 2, 3));       // 6
console.log(sum(10, 20, 30, 40)); // 100

Contrairement à l'ancien objet arguments, les paramètres rest produisent un vrai tableau avec toutes les méthodes de tableau disponibles.

Rest dans la déstructuration de tableau :

javascript
const [first, second, ...remaining] = [1, 2, 3, 4, 5];
console.log(first);     // 1
console.log(second);    // 2
console.log(remaining); // [3, 4, 5]

Rest dans la déstructuration d'objet :

javascript
const { name, ...details } = { name: 'Alice', age: 30, city: 'Paris' };
console.log(name);    // 'Alice'
console.log(details); // { age: 30, city: 'Paris' }

Règle importante : L'élément rest doit toujours être le dernier élément :

javascript
const [first, ...rest, last] = [1, 2, 3]; // SyntaxError!

Patterns courants

Spread et rest permettent de nombreux patterns utiles en JavaScript quotidien.

Cloner des tableaux et objets (copie superficielle) :

javascript
const original = [1, [2, 3], 4];
const clone = [...original];
clone[0] = 99;
console.log(original[0]); // 1 (non affecté)
// Note : les tableaux/objets imbriqués sont toujours partagés (copie superficielle)

Fusionner des objets avec des surcharges :

javascript
const config = {
  ...defaultConfig,
  ...userConfig,
  timestamp: Date.now() // toujours écraser timestamp
};

Retirer des propriétés d'un objet sans mutation :

javascript
const user = { name: 'Alice', password: 'secret', age: 30 };
const { password, ...safeUser } = user;
console.log(safeUser); // { name: 'Alice', age: 30 }
// password est extrait mais n'est pas inclus dans safeUser

Collecter des arguments variadiques :

javascript
const log = (level, ...messages) => {
  console.log(`[${level}]`, ...messages);
};

log('INFO', 'Server started', 'on port 3000');
// [INFO] Server started on port 3000

Ajouter des éléments à un tableau sans mutation :

javascript
const todos = ['Buy milk', 'Clean house'];
const updated = [...todos, 'Walk the dog'];
// le tableau todos original n'est pas modifié

Spread & Rest en action

html
<div id="output"></div>

<script>
  // Spread: merge arrays
  const fruits = ['apple', 'banana'];
  const veggies = ['carrot', 'pea'];
  const food = [...fruits, ...veggies];

  // Spread: merge objects
  const defaults = { color: 'blue', size: 'medium' };
  const custom = { size: 'large', weight: 'bold' };
  const merged = { ...defaults, ...custom };

  // Rest: variadic function
  const sum = (...nums) => nums.reduce((a, b) => a + b, 0);

  // Rest: remove property
  const user = { name: 'Alice', password: '123', role: 'admin' };
  const { password, ...safeUser } = user;

  const output = document.getElementById('output');
  output.innerHTML = `
    <p>Food: [${food.join(', ')}]</p>
    <p>Merged: ${JSON.stringify(merged)}</p>
    <p>sum(1,2,3,4,5): ${sum(1, 2, 3, 4, 5)}</p>
    <p>Safe user: ${JSON.stringify(safeUser)}</p>
  `;
</script>

Quelle est la différence entre spread et rest ?

Prêt à pratiquer ?

Crée ton compte gratuit pour accéder à l'éditeur de code interactif, lancer les défis et suivre ta progression.