Spread, Destructuring & Rest

Trois syntaxes modernes qui simplifient le code

Utilisez les flèches, cliquez ou glissez pour naviguer

Objectifs de la leçon

1. Utiliser le spread operator

Copier et fusionner des tableaux

2. Comprendre référence vs valeur

Pourquoi copier un tableau est important

3. Utiliser le destructuring

Extraire des valeurs en une ligne

4. Maîtriser le rest parameter

Fonctions à arguments variables

Plan du cours

1

Le problème de la copie par référence

Pourquoi const copie = arr ne copie pas

2

Spread operator [...arr]

Copier, fusionner, ajouter des éléments

3

Destructuring [a, b] = arr

Extraire des valeurs en une ligne

4

Destructuring avec rest : [premier, ...reste]

Combiner extraction et collecte

5

Rest parameter dans les fonctions

function f(...args)

6

Cas pratiques combinés

Copier + trier, swap de variables

Le problème : Copie par référence

const copie = arr ne crée PAS une copie!

const original = [1, 2, 3];

const copie = original; // Juste une référence!

copie.push(4);

// copie = [1, 2, 3, 4]

// original = [1, 2, 3, 4] aussi!

Les tableaux sont des types référence, pas des types valeur

copie et original pointent vers le MÊME tableau en mémoire

Visualisation : Même objet en mémoire

Types primitifs (valeur)

let a = 5;

let b = a; // Copie la valeur

b = 10;

// a = 5 (inchangé!)

// b = 10

Tableaux (référence)

let arr = [1,2];

let ref = arr; // Copie la référence

ref.push(3);

// arr = [1, 2, 3] (modifié!)

// ref = [1, 2, 3]

Primitifs (string, number, boolean) = copie de valeur

Objets/Tableaux = copie de référence (pointeur)

Le Spread Operator

Syntaxe : ...arr

"Étale" les éléments d'un tableau

Comme si on les écrivait un par un

const arr = [1, 2, 3];

const copie = [...arr]; // [1, 2, 3]

// Équivalent à: [arr[0], arr[1], arr[2]]

Copier un tableau avec [...arr]

Crée une VRAIE copie indépendante

const original = [1, 2, 3];

const copie = [...original]; // Vraie copie!

copie.push(4);

// copie = [1, 2, 3, 4]

// original = [1, 2, 3] (inchangé!)

original

[1, 2, 3]

copie (après push)

[1, 2, 3, 4]

Fusionner des tableaux

Combiner plusieurs tableaux en un seul

const fruits = ["pomme", "banane"];

const legumes = ["carotte", "poivron"];

const panier = [...fruits, ...legumes];

// panier = ["pomme", "banane", "carotte", "poivron"]

// On peut aussi ajouter des éléments entre les deux

const menu = [...fruits, "orange", ...legumes];

// ["pomme", "banane", "orange", "carotte", "poivron"]

Ajouter des éléments avec spread

Ajouter au début

const arr = [2, 3];

const newArr = [1, ...arr];

// [1, 2, 3]

Ajouter à la fin

const arr = [1, 2];

const newArr = [...arr, 3];

// [1, 2, 3]

Avantage : Crée un nouveau tableau (immuable)

Plus sûr que unshift() ou push() qui modifient l'original

Piège : Copie superficielle

Le spread ne copie pas les sous-objets

const original = [{nom: "Alice"}];

const copie = [...original];

copie[0].nom = "Bob";

// original[0].nom = "Bob" aussi!

Le spread crée une copie "shallow" (superficielle)

Les objets à l'intérieur restent partagés

Le Destructuring

Extraire des valeurs en une seule ligne

"Déballer" les valeurs d'un tableau

Dans des variables distinctes

const [a, b] = [1, 2];

// a = 1, b = 2

Syntaxe de base

const [var1, var2, ...] = tableau

const couleurs = ["rouge", "vert", "bleu"];

const [premiere, deuxieme] = couleurs;

// premiere = "rouge"

// deuxieme = "vert"

Équivalent à :

const premiere = couleurs[0];

const deuxieme = couleurs[1];

Ignorer des éléments

Utiliser des "trous" avec des virgules

const couleurs = ["rouge", "vert", "bleu"];

const [, , troisieme] = couleurs;

// troisieme = "bleu"

// Les deux virgules ignorent les 2 premiers

// Ignorer le premier, garder le deuxième

const [, deuxieme] = couleurs;

// deuxieme = "vert"

Valeurs par défaut

Définir une valeur si l'élément n'existe pas

const couleurs = ["rouge"];

const [premiere, deuxieme = "vert"] = couleurs;

// premiere = "rouge"

// deuxieme = "vert" (valeur par défaut)

Utile quand on ne connaît pas la taille du tableau

Évite les undefined inattendus

Destructuring + Rest

Extraire ET collecter en même temps

[premier, ...reste] = tableau

Extrait le premier, collecte le reste

const [premier, ...reste] = [1, 2, 3, 4];

// premier = 1

// reste = [2, 3, 4]

Exemples pratiques

Séparer le premier élément du reste

const nombres = [10, 20, 30, 40];

const [premier, ...autres] = nombres;

// premier = 10, autres = [20, 30, 40]

Garder les premiers, collecter le reste

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

// a = 1, b = 2, reste = [3, 4, 5]

Le Rest Parameter

Fonctions à nombre variable d'arguments

Collecte tous les arguments dans un tableau

Syntaxe : ...args dans les paramètres

function somme(...nombres) {

return nombres.reduce((a, b) => a + b, 0);

}

somme(1, 2, 3); // 6

Syntaxe du rest parameter

function nom(...args) { }

args devient un tableau contenant tous les arguments

function afficher(...args) {

console.log(args); // C'est un tableau!

}

afficher("a", "b", "c");

// ["a", "b", "c"]

Avant : on utilisait l'objet "arguments"

Maintenant : rest parameter = vrai tableau avec toutes les méthodes

Combiner paramètres fixes et rest

Le rest doit TOUJOURS être le dernier paramètre

function presenter(nom, ...hobbies) {

console.log(`${nom} aime:`);

hobbies.forEach(h => console.log(`- ${h}`));

}

presenter("Alice", "JS", "CSS", "HTML");

// Résultat:

Alice aime:

- JS

- CSS

- HTML

Piège : Rest en dernier!

Le rest parameter doit toujours être le dernier

Erreur de syntaxe!

function f(...args, x) { }

// SyntaxError!

Correct

function f(x, ...args) { }

// OK!

Le Swap de variables

Les étudiants adorent cette syntaxe!

Ancienne méthode

let temp = a;

a = b;

b = temp;

// 3 lignes!

Avec destructuring

[a, b] = [b, a];

// 1 ligne!

let x = 10, y = 20;

[x, y] = [y, x];

// x = 20, y = 10

Copier et trier en une ligne

Spread + sort() sans modifier l'original

const nombres = [3, 1, 4, 2];

const trie = [...nombres].sort((a, b) => a - b);

// trie = [1, 2, 3, 4]

// nombres = [3, 1, 4, 2] (inchangé!)

Sans spread :

nombres.sort(); // Modifie l'original!

Combiner spread et rest

Passer un tableau comme arguments à une fonction

function somme(...nombres) {

return nombres.reduce((a, b) => a + b, 0);

}

const arr = [1, 2, 3, 4];

somme(...arr); // 10

// Équivalent à: somme(1, 2, 3, 4)

// Spread "étale" le tableau en arguments

// Rest "rassemble" les arguments en tableau

Même syntaxe (...), contextes différents!

Spread vs Rest : Récapitulatif

Spread [...arr]

Étale les valeurs

À droite du = ou dans les appels

Crée un nouveau tableau

const copie = [...arr];

f(...arr);

Rest ...args

Rassemble les valeurs

À gauche du = ou dans les paramètres

Crée un tableau à partir d'éléments

const [a, ...reste] = arr;

function f(...args) { }

Même syntaxe (...), mais sens opposé selon le contexte!

Points Clés à Retenir

1

Les trois points ... ont un sens différent selon le contexte

2

Spread étale (droite du =), Rest rassemble (gauche ou params)

3

Spread = copie superficielle (shallow)

4

Le swap [a, b] = [b, a] est magique!

Maîtrisez ces trois syntaxes = code plus propre et moderne

Pièges Courants

1. Confondre spread et rest

Même syntaxe (...), contextes différents

Spread = étale | Rest = rassemble

2. Rest doit être le dernier paramètre

function f(x, ...args) {} // OK

function f(...args, x) {} // ERREUR

3. Copie superficielle (shallow)

Le spread ne copie PAS les sous-objets

const arr = [{x: 1}];

const copie = [...arr];

copie[0].x = 99; // Modifie l'original!

Résumé

[...arr]

Spread

Copier, fusionner, étaler

[a, b] = arr

Destructuring

Extraire des valeurs

...args

Rest

Rassembler en tableau

Trois syntaxes, un même but

Simplifier et moderniser le code JavaScript