Avant 2015, créer un modèle d'objet en JavaScript demandait une fonction constructeur, une manipulation de prototype et une bonne dose de patience.
class a rassemblé tout cela dans une déclaration unique. Le mécanisme sous-jacent n'a pas changé, la lisibilité si.
Définition
class déclare un modèle à partir duquel des objets seront fabriqués avec new. La déclaration réunit le constructeur, les méthodes partagées par toutes les instances et les champs qui appartiennent à chacune.
class Panier {
#articles = [];
ajouter(nom, prix) {
this.#articles.push({ nom, prix });
return this;
}
get total() {
return this.#articles.reduce((somme, article) => somme + article.prix, 0);
}
}
const panier = new Panier();
panier.ajouter("Clavier", 79).ajouter("Souris", 29);
console.log(panier.total); // 108Trois choses méritent l'attention ici. Le champ #articles est privé et n'existe pas en dehors de la classe. Chaque méthode renvoie this, ce qui permet d'enchaîner les appels. Et total se lit comme une propriété ordinaire alors qu'un calcul se produit à chaque lecture.
Ce qu'une classe peut contenir
Le corps d'une classe n'accepte pas n'importe quoi : ni virgules entre les membres, ni instructions libres. Voici la liste complète de ce qui peut y figurer.
| Élément | Rôle |
|---|---|
| constructor | Prépare l'instance au moment de sa création |
| Méthode | Comportement partagé par toutes les instances |
| Champ | Donnée propre à chaque instance, déclarée en tête |
| Champ préfixé par un dièse | Donnée strictement inaccessible depuis l'extérieur |
| get et set | Une propriété calculée derrière une lecture ordinaire |
| Membre static | Attaché à la classe elle-même, pas aux instances |
Le champ privé est la nouveauté qui change le plus de choses au quotidien : là où un souligné en tête de nom n'était qu'une convention, le dièse est appliqué par le langage, et tout accès depuis l'extérieur est refusé à l'analyse du fichier.
Du sucre au-dessus des prototypes
Une classe n'introduit aucun mécanisme nouveau dans le moteur. Elle produit une fonction, et ses méthodes atterrissent sur le prototype, exactement comme avant.
class Chien {
aboyer() { return "Ouaf"; }
}
const rex = new Chien();
console.log(typeof Chien); // "function"
console.log(Object.getPrototypeOf(rex) === Chien.prototype); // trueDeux différences de comportement méritent tout de même d'être connues. Le corps d'une classe s'exécute toujours en mode strict, même dans un fichier qui ne l'est pas. Et une classe ne peut pas être utilisée avant sa déclaration : contrairement à une function, elle reste inaccessible jusqu'à la ligne qui la définit.
Questions fréquentes
Faut-il des classes pour bien écrire du JavaScript ?
Non. Une fonction qui renvoie un objet littéral fait souvent l'affaire, et beaucoup de code moderne s'en tient là. La classe devient intéressante quand plusieurs objets partagent un comportement, quand un état doit rester privé, ou quand une famille de types se dessine avec extends.
Peut-on ajouter une méthode après la déclaration ?
Techniquement oui, en écrivant sur le prototype de la classe, et toutes les instances existantes en héritent aussitôt. C'est une pratique à éviter dans du code applicatif : la déclaration cesse de dire la vérité sur ce que la classe sait faire, et les outils d'analyse ne suivent plus.
Et les classes de TypeScript, sont-ce les mêmes ?
Ce sont les mêmes classes, augmentées d'annotations vérifiées à la compilation : types des champs, visibilité, propriétés en lecture seule. Le code produit reste du JavaScript ordinaire. Notre formation TypeScript détaille ce que ces annotations attrapent et ce qu'elles ne peuvent pas attraper.