La copie superficielle
Copier un objet sans partager ses propriétés imbriquées.
Objectifs
À la fin de cette leçon, vous saurez :
- dupliquer un objet ou un tableau sans partager la référence ;
- utiliser la syntaxe d'étalement
...; - comprendre ce que copie réellement une « copie superficielle » ;
- identifier les propriétés imbriquées qui restent partagées.
🔗 Pour vous rafraîchir la mémoire : objets et références · le passage de paramètres
Le problème
On veut deux objets indépendants, sans réécrire chaque propriété à la main :
const original = { name: "Paul", age: 20 };
const copie = original; // NON : même objet
copie.age = 21;
console.log(original.age); // 21 : catastrophe
La solution de base : l'étalement
const original = { name: "Paul", age: 20 };
const copie = { ...original }; // nouveau objet, propriétés recopiées
copie.age = 21;
console.log(original.age); // 20 : intact
console.log(copie.age); // 21
console.log(copie === original); // false : deux objets distincts
{ ...original } fabrique un nouvel objet et y recopie les propriétés du premier niveau. Même mécanisme pour les tableaux :
const nombres = [1, 2, 3];
const clone = [...nombres];
clone.push(4);
console.log(nombres.length); // 3
console.log(clone.length); // 4
Autres façons équivalentes pour les tableaux : nombres.slice() (sans argument) ou Array.from(nombres).
Pourquoi « superficielle »
La copie ne concerne que le premier niveau. Si une propriété contient elle-même un objet, c'est la référence qui est recopiée :
const original = {
name: "Paul",
adresse: { ville: "Lyon" },
};
const copie = { ...original };
copie.adresse.ville = "Paris"; // mutation de l'objet imbriqué…
console.log(original.adresse.ville); // "Paris" : partagé !
console.log(copie.adresse === original.adresse); // true
Schéma mental :
original ─→ { name, adresse ─┐
├─→ { ville } (un seul objet imbriqué)
copie ─→ { name, adresse ─┘
Le premier niveau est dupliqué ; les niveaux profonds restent communs.
Copier en profondeur (aperçu)
Pour tout dupliquer, y compris les imbrications :
const copieProfonde = JSON.parse(JSON.stringify(original));
Cette astuce fonctionne pour des données simples (textes, nombres, booléens) mais perd ce qui n'est pas représentable en JSON : fonctions, undefined, dates transformées en chaînes. Des outils dédiés existent (structuredClone, bibliothèques) — nous y reviendrons quand le besoin sera réel.
Exercice
- Créez
livre = { titre: "Cours", pages: 120 }, copiez-le avec..., modifiez le nombre de pages de la copie et vérifiez l'original.
const a = { tags: ["js", "web"] };
const b = { ...a };
b.tags.push("memoire");
console.log(a.tags);
Prédisez puis expliquez.
3. Écrivez fusionner(defauts, options) qui renvoie un nouvel objet contenant les propriétés des deux (les options gagnent en cas de conflit), sans modifier ni defauts ni options. Indice : { ...a, ...b }.
4. Écrivez retirerDernier(liste) qui renvoie un nouveau tableau privé du dernier élément, sans toucher à l'original.
5. Expliquez en une phrase pourquoi on parle de copie « superficielle ».
Résumé
{ ...obj }et[ ...tab ]créent un nouvel objet au contenu du premier niveau.- Les références imbriquées sont recopiées telles quelles : profondeur 1 seulement.
- La comparaison
===après copie vautfalse; après simple affectation,true.
Correction disponibleCherchez d’abord par vous-même.Voir la correction
Correction
Réponses détaillées
Exercice 1.
const livre = { titre: "Cours", pages: 120 };
const exemplaire = { ...livre };
exemplaire.pages = 150;
console.log(livre.pages); // 120
console.log(exemplaire.pages); // 150
Exercice 2. Affiche ["js", "web", "memoire"]. La copie superficielle a recopié la référence du tableau tags : les deux objets partagent le même tableau interne, donc le push est visible partout.
Exercice 3.
function fusionner(defauts, options) {
return { ...defauts, ...options };
}
const defauts = { theme: "clair", langue: "fr" };
const options = { theme: "sombre" };
const config = fusionner(defauts, options);
console.log(config); // { theme: "sombre", langue: "fr" }
console.log(defauts.theme); // "clair" : intact
Les étalements successifs écrasent les doublons dans l'ordre d'écriture : options passe en dernier et gagne.
Exercice 4.
function retirerDernier(liste) {
return liste.slice(0, -1);
}
// ou avec l'étalement :
function retirerDernierBis(liste) {
const copie = [...liste];
copie.pop();
return copie;
}
Question 5. Exemple de réponse attendue : « seul le niveau supérieur est copié ; tout ce qui est plus profond reste partagé par référence — comme si l'on n'avait photocopié que la première page d'un dossier ».