Prototype en JavaScript : l'objet auquel un autre objet délègue

Chaque objet JavaScript pointe vers un autre objet, son prototype, où le moteur va chercher ce qu'il ne trouve pas sur l'objet lui-même.
3 min de lecture
Believemy logo

Un tableau vide ne contient rien, et pourtant il sait trier, filtrer, se transformer. Un objet créé avec deux propriétés répond à des méthodes que personne n'a écrites pour lui. Ces capacités ne sont pas copiées : elles sont empruntées.

Le mécanisme s'appelle le prototype, et c'est la seule forme de partage de comportement du langage, y compris derrière le mot-clé class.


Définition

Le prototype d'un objet est un autre objet auquel il délègue les recherches. Quand vous lisez une propriété absente, le moteur la cherche sur ce prototype, puis sur le prototype de celui-ci, jusqu'à tomber sur null.

JAVASCRIPT
const liste = [1, 2, 3];

console.log(Object.getPrototypeOf(liste) === Array.prototype);          // true
console.log(Object.getPrototypeOf(Array.prototype) === Object.prototype); // true
console.log(Object.getPrototypeOf(Object.prototype));                   // null

console.log(liste.hasOwnProperty("length")); // true, propriété propre
console.log("map" in liste);                 // true, trouvée plus haut

Le tableau ne possède que ses éléments et sa longueur. map et les autres vivent une fois pour toutes sur Array.prototype, partagées par tous les tableaux du programme.

La chaîne de prototypesLa lecture de p.etiquette part de l'objet p, qui ne possède que nom, remonte à Produit.prototype où la propriété est trouvée, et s'arrête là. Les maillons suivants, Object.prototype puis null, existent toujours mais ne sont pas parcourus : leur lien est tracé en pointillé.p.etiquette : où le moteur cherchep = new Produit("Clavier")propre : nometiquette absenteProduit.prototypepropre : etiquettetrouvée iciObject.prototypepropre : toStringnon parcourunullfin de la chaînedélègue àla recherche s'arrête au premier maillonqui possède la propriété


prototype et le prototype, deux choses différentes

La confusion vient d'un mot employé pour deux réalités. Ce tableau à trois colonnes les sépare.

ÉcriturePorté parCe que c'est
Produit.prototypeUne fonction constructriceL'objet que recevront les instances
Object.getPrototypeOf(p)N'importe quel objetLe prototype dont il hérite
p.__proto__N'importe quel objetLa même chose, écriture historique

Seules les fonctions portent une propriété prototype. Elle ne sert qu'au moment où la fonction est appelée avec new.

JAVASCRIPT
function Produit(nom) {
  this.nom = nom;
}

Produit.prototype.etiquette = function () {
  return "Produit : " + this.nom;
};

const p = new Produit("Clavier");
console.log(p.etiquette());                 // Produit : Clavier
console.log(p.hasOwnProperty("etiquette")); // false, elle est sur le prototype


Ce que ça change à l'usage

  • Une méthode existe en un seul exemplaire. Mille instances partagent la même fonction, pas mille copies.
  • instanceof interroge la chaîne. Il ne compare pas des types, il remonte les prototypes.
  • Une class ne change rien à tout ça. Elle écrit la même structure avec une syntaxe plus lisible.
Bon à savoir

Modifier un prototype natif, par exemple ajouter une méthode à Array.prototype, est une mauvaise idée : le nom choisi peut heurter un futur ajout du langage, et le comportement change partout.


Questions fréquentes

Question

Pourquoi __proto__ est-il déconseillé ?

Parce que c'est un accès historique, conservé pour ne pas casser le web existant, et qu'il est modifiable. Changer le prototype d'un objet déjà utilisé dégrade fortement les optimisations du moteur. Préférez Object.getPrototypeOf() en lecture, et Object.create() à la création.


Question

Comment créer un objet sans aucun prototype ?

Avec Object.create(null). L'objet obtenu n'hérite de rien, pas même de toString. C'est utile pour un dictionnaire alimenté par des données extérieures, où une clé nommée constructor ne doit pas heurter une propriété héritée.


Question

La délégation coûte-t-elle du temps à chaque lecture ?

La recherche remonte la chaîne, donc une propriété située trois niveaux plus haut demande trois étapes. Les moteurs mettent ces chemins en cache et le coût reste invisible. Notre formation JavaScript détaille cette chaîne avant d'aborder les classes, dans cet ordre précisément.

Termes connexes

Découvrez notre glossaire JavaScript

Tous les mots de JavaScript expliqués simplement : mots-clés, objets natifs, méthodes, erreurs et concepts. Définitions claires et exemples qui tournent, pour apprendre et pour se dépanner.

Partager cet article

Tu veux nous aider ? Fais un lien vers cet article sur tes réseaux ou encore mieux : sur ton site, dans un article ou dans ta newsletter.