Leçon 1/5 10 min

Les classes en JavaScript

class, constructor, champs privés #, get/set, extends et super, méthodes statiques. La POO appliquée en JavaScript, avec un éditeur exécutable.

FR EN

JavaScript aussi a des classes

Depuis 2015 (ES6), JavaScript a le mot-clé class. Si tu as suivi le cours « La POO expliquée simplement », tu retrouves exactement les mêmes idées : propriétés, méthodes, constructeur, héritage. La syntaxe est très proche de PHP ou Java.

class Compte {
  constructor(titulaire) {     // appelé par "new"
    this.titulaire = titulaire;
    this.solde = 0;
  }
  deposer(montant) {           // une méthode
    this.solde += montant;
  }
}

const c = new Compte("Alice");
c.deposer(120);
console.log(c.solde);          // 120

Différence avec PHP : on n'écrit pas $ devant les variables, et on accède aux membres avec un point (c.solde), pas une flèche.

La classe Compte est le moule : elle contient le constructeur et les méthodes partagées. Chaque appel à new fabrique une instance avec ses propres données, mais qui réutilise les méthodes de la classe. La classe (le moule) Les instances class Compte constructeur constructor() méthodes partagées deposer() retirer() écrites une seule fois new new compteAlice titulaire : "Alice" solde : 120 compteBob titulaire : "Bob" solde : 0 Données propres à chaque instance, méthodes partagées par la classe.
Une seule classe, autant d'instances qu'on veut : chacune a ses données, toutes partagent les mêmes méthodes.

Champs privés avec #

Longtemps JS n'avait pas de vrai privé. Depuis peu, le préfixe # crée un champ réellement privé : inaccessible hors de la classe (encapsulation, comme vu en POO).

class Compte {
  #solde = 0;                  // privé : invisible de l'extérieur
  deposer(m) { if (m > 0) this.#solde += m; }
  get solde() { return this.#solde; }   // accesseur en lecture
}

const c = new Compte();
c.deposer(50);
console.log(c.solde);   // 50  (via le getter)
// c.#solde            // ❌ SyntaxError : champ privé hors de la classe

Le get solde() est un accesseur : on l'utilise comme une propriété (c.solde, sans parenthèses) mais c'est une méthode. Il existe aussi set pour écrire avec validation.

Héritage : extends et super

class CompteEpargne extends Compte {
  constructor(taux) {
    super();              // appelle le constructeur parent (obligatoire avant this)
    this.taux = taux;
  }
  ajouterInterets() {
    this.deposer(this.solde * this.taux);   // réutilise la méthode héritée
  }
}

Et les méthodes statiques (static) appartiennent à la classe, pas à une instance : Compte.creerVide() plutôt que c.creerVide(). Utile pour des fabriques ou des utilitaires.

Essaie (rendu à droite)

Une vraie classe JS qui tourne dans ton navigateur. Modifie-la, clique sur « Exécuter ».

Essaie toi-même
Comment déclare-t-on un champ vraiment privé dans une classe JS moderne ?
Dans un constructeur d'une classe enfant, que fait super() ?
Prochaine étape

Les classes JS cachent un piège que les débutants rencontrent tous : le mot this qui « se perd ». Et au fond, les classes ne sont que du sucre sur les prototypes. On démonte tout ça.

Leçon 2 : this et les prototypes →

JavaScript has classes too

Since 2015 (ES6), JavaScript has the class keyword. If you took « OOP explained simply », you'll recognize the exact same ideas: properties, methods, constructor, inheritance. The syntax is very close to PHP or Java.

class Compte {
  constructor(titulaire) {     // called by "new"
    this.titulaire = titulaire;
    this.solde = 0;
  }
  deposer(montant) {           // a method
    this.solde += montant;
  }
}

const c = new Compte("Alice");
c.deposer(120);
console.log(c.solde);          // 120

Difference from PHP: no $ before variables, and you access members with a dot (c.solde), not an arrow.

The Account class is the mold: it holds the constructor and the shared methods. Each call to new builds an instance with its own data, but reusing the class methods. The class (the mold) The instances class Account constructor constructor() shared methods deposit() withdraw() written only once new new aliceAccount owner: "Alice" balance: 120 bobAccount owner: "Bob" balance: 0 Data is per-instance, methods are shared by the class.
One class, as many instances as you want: each has its own data, all share the same methods.

Private fields with #

For a long time JS had no real privacy. Recently, the # prefix creates a truly private field: unreachable outside the class (encapsulation, as seen in OOP).

class Compte {
  #solde = 0;                  // private: invisible from outside
  deposer(m) { if (m > 0) this.#solde += m; }
  get solde() { return this.#solde; }   // read accessor
}

const c = new Compte();
c.deposer(50);
console.log(c.solde);   // 50  (via the getter)
// c.#solde            // ❌ SyntaxError: private field outside the class

get solde() is an accessor: you use it like a property (c.solde, no parentheses) but it's a method. There's also set to write with validation.

Inheritance: extends and super

class CompteEpargne extends Compte {
  constructor(taux) {
    super();              // calls the parent constructor (required before this)
    this.taux = taux;
  }
  ajouterInterets() {
    this.deposer(this.solde * this.taux);   // reuses the inherited method
  }
}

And static methods (static) belong to the class, not an instance: Compte.creerVide() rather than c.creerVide(). Useful for factories or utilities.

Try it (preview on the right)

A real JS class running in your browser. Edit it, click "Run".

Try it yourself
Next step

JS classes hide a trap every beginner meets: the word this that "gets lost". And deep down, classes are just sugar over prototypes. We'll take it all apart.

Lesson 2: this and prototypes →
Rappel libre

Sans remonter dans la leçon : qu'est-ce qui est partagé par toutes les instances d'une classe et qu'est-ce qui est propre à chacune ? Et à quoi sert le préfixe # sur un champ ?

Les méthodes (et le constructeur) sont écrites une seule fois et partagées par toutes les instances ; les données posées sur this dans le constructeur (ex. this.titulaire, le #solde) sont propres à chaque objet créé avec new. Le préfixe # rend un champ réellement privé : il n'est lisible ni modifiable hors de la classe (c.#solde hors classe est une SyntaxError), d'où l'usage d'un getter get solde() pour le lire.
Accepter ou rejeter le code de l'IA

L'IA propose ce composant Minuteur. Ton rôle de relecteur : l'accepter tel quel ou le rejeter, et dire pourquoi.

class Minuteur {
  #secondes = 0;
  demarrer() {
    setInterval(function () {
      this.#secondes++;            // incrémente chaque seconde
      console.log(this.#secondes);
    }, 1000);
  }
}
new Minuteur().demarrer();
Rejeter : ce code plante. La function classique passée à setInterval a son propre this (ici undefined en mode module, ou l'objet global ailleurs), pas l'instance. À la première seconde, this.#secondes lève une erreur car le champ privé n'existe pas sur cet objet. Correctif : une fonction fléchée () => { this.#secondes++; }, qui capture le this de demarrer(). C'est exactement la fuite de this annoncée pour la leçon suivante : les classes ne lient pas this toutes seules.
Besoin d'un développeur pour votre projet ?

Réponse sous 24h · Sans engagement