5.7 Types de Valeurs VS Types de Réferences

JavaScript distingue deux grandes catégories de types. D'un côté les primitives ou types de valeur : number, string, boolean, symbol, undefined, null. De l'autre les types de référence : objets, fonctions, tableaux (les fonctions et tableaux étant eux-mêmes des objets sous le capot).

Cette distinction est cruciale car les deux catégories se comportent radicalement différemment quand on les copie. Comprendre ce point est indispensable avant d'aborder les prototypes.

Primitives : copie par valeur

Avec une primitive, la valeur est stockée directement dans la variable. Quand on copie une variable, sa valeur est dupliquée dans la nouvelle variable. Les deux sont totalement indépendantes : modifier l'une n'affecte pas l'autre.

let x = 10;
							let y = x;
							x = 20;
							console.log(x, y); // 20 10

Objets : copie par référence

Avec un objet, c'est différent. L'objet est stocké quelque part en mémoire, et la variable contient seulement l'adresse (la référence) de cet emplacement. Copier la variable copie la référence, pas l'objet : on se retrouve avec deux variables qui pointent vers le même objet en mémoire.

let a = { value: 10 };
							let b = a;
							a.value = 20;
							console.log(b.value); // 20 — modifié aussi !

Conséquences avec les fonctions

Le même comportement s'observe quand on passe une variable en argument. Une primitive est copiée — la fonction reçoit une variable locale indépendante. Modifier ce paramètre n'a aucun effet sur la variable d'origine.

function increase(n) { n++; }
							
							let num = 10;
							increase(num);
							console.log(num); // 10 — inchangé

En revanche, si on passe un objet, la fonction reçoit une copie de la référence, mais cette référence pointe vers le même objet. Toute modification de ses propriétés sera visible à l'extérieur.

function increase(obj) { obj.value++; }
							
							const num = { value: 10 };
							increase(num);
							console.log(num.value); // 11 — modifié !

Retenez la règle d'or : primitives copiées par valeur, objets copiés par référence. Cette différence explique 80% des bugs de débutant et reste un piège classique même pour les développeurs expérimentés.

En résumé

JavaScript distingue deux catégories fondamentales : les types de valeurs (primitifs : nombres, chaînes, symboles, undefined, null) et les types de référence (objets, fonctions, tableaux). La distinction cruciale réside dans leur comportement lors de l'assignation et de la copie : les primitives sont copiées par valeur, créant des variables indépendantes, tandis que les objets sont copiés par référence, permettant à plusieurs variables de pointer vers le même emplacement en mémoire. Cette différence impacte directement la propagation des modifications entre variables et lors du passage d'arguments aux fonctions.

Points clés

  • Deux catégories de types en JavaScript : types de valeurs/primitifs (nombres, chaînes, symboles, undefined, null) et types de référence (objets, fonctions, tableaux)
  • Les primitives sont copiées par valeur : l'assignation crée une copie indépendante, les modifications à l'une n'affectent pas l'autre
  • Les objets sont copiés par référence : l'adresse mémoire est copiée, plusieurs variables pointent vers le même objet, les modifications sont visibles partout
  • Passage de primitives aux fonctions : une copie indépendante est créée, les modifications dans la fonction n'affectent pas la variable d'origine
  • Passage d'objets aux fonctions : la référence est transmise, les modifications à l'intérieur de la fonction affectent l'objet d'origine

Questions fréquentes

Quelle est la différence de comportement entre les types de valeurs et les types de référence ?

Les types de valeurs (primitifs) stockent leur valeur directement dans la variable et sont copiés par valeur lors d'assignation. Les types de référence (objets) stockent une référence mémoire et sont copiés par référence, ce qui signifie que plusieurs variables peuvent pointer vers le même objet.

Pourquoi modifier une primitive dans une fonction n'affecte pas la variable d'origine ?

Les primitives sont copiées par valeur. Lorsque vous passez une primitive à une fonction, sa valeur est copiée dans un paramètre local indépendant, créant deux variables séparées et complètement indépendantes.

Pourquoi modifier un objet dans une fonction affecte-t-il l'objet d'origine ?

Les objets sont copiés par référence. Lorsque vous passez un objet à une fonction, c'est l'adresse mémoire (référence) qui est copiée, donc le paramètre local et la variable d'origine pointent tous deux vers le même objet en mémoire.