À propos de ce cours
Chapitre 16 — La programmation orientée objet · 16.6 Les prototypes : ce qui se cache derrière les classes
• comprendre que les classes JavaScript reposent sur les prototypes ;
• suivre la chaîne des prototypes pour trouver une propriété ;
• distinguer propriétés propres et propriétés héritées ;
• lire du code ancien écrit avec des fonctions constructeurs.
1. Une classe est une fonction
Nous avons vu que typeof CompteBancaire vaut "function". En JavaScript, les classes sont une
syntaxe plus agréable (on parle de « sucre syntaxique ») pour un mécanisme plus ancien : les prototypes.
Chaque objet possède un lien caché, appelé [[Prototype]], vers un autre objet. Quand on lit une propriété absente de l'objet,
JavaScript la cherche dans son prototype, puis dans le prototype du prototype, et ainsi de suite jusqu'à null.

Figure 1 — La recherche d'une propriété remonte la chaîne.
2. Observer les prototypes
class CompteBancaire {
constructor(titulaire, solde) {
this.titulaire = titulaire;
this.solde = solde;
}
deposer(montant) {
this.solde += montant;
}
}
const a = new CompteBancaire("Amina", 100);
const b = new CompteBancaire("Sami", 50);
// 1. Les données sont SUR l'objet, les méthodes sont sur le PROTOTYPE
console.log("Propriétés propres :", Object.keys(a));
console.log("a possède deposer ?", Object.hasOwn(a, "deposer"));
console.log("deposer est dans le prototype ?", Object.hasOwn(CompteBancaire.prototype, "deposer"));
console.log("Une seule fonction partagée ?", a.deposer === b.deposer);
// 2. La chaîne des prototypes
const p1 = Object.getPrototypeOf(a);
const p2 = Object.getPrototypeOf(p1);
console.log(p1 === CompteBancaire.prototype, p2 === Object.prototype, Object.getPrototypeOf(p2));
// 3. toString vient de Object.prototype, tout en haut de la chaîne
console.log("a.toString() :", a.toString());
// 4. Ajouter une méthode au prototype la donne à TOUTES les instances, même existantes
CompteBancaire.prototype.afficher = function () {
return `${this.titulaire} : ${this.solde} DT`;
};
console.log(b.afficher());
// 5. Une propriété propre « masque » celle du prototype
a.afficher = () => "Je masque la méthode du prototype";
console.log(a.afficher(), "|", b.afficher());
Résultat dans la console
Propriétés propres : [ 'titulaire', 'solde' ] a possède deposer ? false deposer est dans le prototype ? true Une seule fonction partagée ? true true true null a.toString() : [object Object] Sami : 50 DT Je masque la méthode du prototype | Sami : 50 DT
- Les données (
titulaire,solde) sont des propriétés propres de chaque objet. - Les méthodes sont rangées une seule fois dans
Classe.prototype: toutes les instances les partagent. toStringvient deObject.prototype, en haut de presque toutes les chaînes.- Ajouter une méthode au prototype la rend disponible pour toutes les instances, même déjà créées.
- Une propriété propre masque une propriété de même nom plus haut dans la chaîne.
3. Avant les classes
Avant ES2015, on écrivait des fonctions constructeurs. Vous en rencontrerez dans du code ancien et dans des bibliothèques :
// Ce qu'on écrivait AVANT les classes (ES5) : fonction constructeur + prototype
function CompteBancaire(titulaire, solde) {
this.titulaire = titulaire;
this.solde = solde;
}
CompteBancaire.prototype.deposer = function (montant) {
this.solde += montant;
};
// Héritage « à la main »
function CompteEpargne(titulaire, solde, taux) {
CompteBancaire.call(this, titulaire, solde); // équivalent de super(...)
this.taux = taux;
}
Object.setPrototypeOf(CompteEpargne.prototype, CompteBancaire.prototype); // équivalent de extends
CompteEpargne.prototype.ajouterInterets = function () {
this.deposer(this.solde * this.taux);
};
const e = new CompteEpargne("Lina", 1000, 0.05);
e.ajouterInterets();
console.log(e.solde, e instanceof CompteBancaire);
Résultat dans la console
1050 true
| Avec class | Équivalent avec les prototypes |
|---|---|
class A { constructor(x) { this.x = x; } } | function A(x) { this.x = x; } |
m() { … } dans la classe | A.prototype.m = function () { … }; |
class B extends A | Object.setPrototypeOf(B.prototype, A.prototype) |
super(x) | A.call(this, x) |
Modifier le prototype des objets intégrés (
Array.prototype, String.prototype…) est à éviter absolument :
votre méthode pourrait entrer en conflit avec une future version de JavaScript ou avec une bibliothèque.• Les classes reposent sur les prototypes :
typeof Classe === "function". • Chaque objet a un
[[Prototype]]; une propriété absente est cherchée en remontant la chaîne jusqu'à null. • Données = propriétés propres de l'objet ; méthodes = dans
Classe.prototype, partagées.•
Object.getPrototypeOf, Object.hasOwn pour inspecter ; ne jamais modifier les prototypes intégrés.🛠 Activité 6 — Explorer la chaîne des prototypes
Mission : Utilisez la console pour remonter les chaînes de prototypes d'objets que vous connaissez.
Questions pour avancer (répondez dans votre compte rendu, puis appliquez dans votre projet) :
- Pour un tableau
[1, 2, 3], remontez la chaîne avecObject.getPrototypeOfjusqu'ànull. Combien de maillons comptez-vous ? Où se trouve la méthodemap? EttoString? - Faites le même exercice avec un
ProduitPhysiquede la leçon 16.5. Dessinez la chaîne et indiquez dans quel maillon se trouve chaque méthode et chaque getter. - Pourquoi
Object.keys(livre)n'affiche-t-il pasprixTTC? Quelle méthode permet de savoir si une propriété est propre ou héritée ? - Réécrivez votre classe
Etudiant(activité 1) sous forme de fonction constructeur avecprototype. Le comportement est-il identique ? Qu'est-ce qui est plus pénible à écrire ? - Créez un objet avec
Object.create(null). Possède-t-iltoString? À quoi un tel objet peut-il servir ? - Un collègue ajoute
Array.prototype.somme = function () { … }dans son projet. Donnez-lui deux raisons de ne pas le faire et proposez une alternative.
Je vérifie / je rends :
- ☐ Le schéma de la chaîne de la question 2.
- ☐ Les réponses aux autres questions.
← 16.5 L'héritage des classes (extends et super)16.7 Polymorphisme et composition →