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 (...) 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 :
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 :
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 :
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 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 :
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)); // 100Contrairement à 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 :
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 :
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 :
const [first, ...rest, last] = [1, 2, 3]; // SyntaxError!Spread et rest permettent de nombreux patterns utiles en JavaScript quotidien.
Cloner des tableaux et objets (copie superficielle) :
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 :
const config = {
...defaultConfig,
...userConfig,
timestamp: Date.now() // toujours écraser timestamp
};Retirer des propriétés d'un objet sans mutation :
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 safeUserCollecter des arguments variadiques :
const log = (level, ...messages) => {
console.log(`[${level}]`, ...messages);
};
log('INFO', 'Server started', 'on port 3000');
// [INFO] Server started on port 3000Ajouter des éléments à un tableau sans mutation :
const todos = ['Buy milk', 'Clean house'];
const updated = [...todos, 'Walk the dog'];
// le tableau todos original n'est pas modifié<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 ?