Un guide complet avec des exemples



JavaScript, langage aux multiples facettes, offre la possibilité de concevoir des programmes selon des approches fonctionnelles, orientées objet et impératives.

Les classes, piliers du paradigme orienté objet, sont essentielles à maîtriser. Cet article se veut un guide complet pour comprendre leur nature et leur usage en JavaScript.

Qu’est-ce qu’une classe en JavaScript ?

La programmation orientée objet repose sur une modélisation des systèmes via des groupes d’objets interagissant entre eux. Ces objets, pour opérer, stockent des données au sein de propriétés et exécutent des actions par le biais de méthodes. Une classe définit précisément les propriétés et les méthodes qui caractérisent les objets d’un même type. Ainsi, les classes agissent comme des schémas pour la création d’objets.

Termes clés relatifs aux classes

Pour une compréhension partagée, voici un éclaircissement des termes fondamentaux relatifs aux classes que nous utiliserons dans cet article. Si vous êtes déjà familiarisé avec la programmation orientée objet, vous pouvez directement passer à la section suivante.

❇️ Une classe est un modèle, un schéma de base pour la construction d’un objet. Elle sert de fondation pour la création d’objets de ce type. L’acte de créer un objet à partir d’une classe est appelé instanciation.

❇️ Un membre de classe désigne tout élément appartenant à la classe, qu’il s’agisse de méthodes ou de propriétés.

❇️ Une propriété est un membre de classe dont l’objectif principal est de contenir des valeurs, qu’elles soient simples comme des nombres ou des chaînes de caractères, ou complexes comme des objets et des tableaux.

❇️ Certaines propriétés, qualifiées de privées, ne sont accessibles que depuis l’intérieur de la classe. D’autres, dites publiques, sont accessibles tant de l’intérieur que de l’extérieur de la classe.

❇️ Une méthode est une fonction définie à l’intérieur d’une classe. Elle est donc rattachée à la classe et peut accéder à ses propriétés, qu’elles soient publiques ou privées. De même que les propriétés, il existe des méthodes publiques et privées.

❇️ Certaines méthodes servent d’interface entre le code extérieur à la classe et les propriétés internes. On distingue deux catégories : les getters, qui permettent de récupérer la valeur des propriétés, et les setters, qui permettent de les modifier.

❇️ Les membres statiques, quant à eux, ne sont accessibles qu’à travers la classe elle-même et non pas via ses instances. À l’inverse, les membres non statiques sont uniquement accessibles via les instances de la classe, après que celle-ci ait été instanciée.

Lors de l’instanciation d’une classe, une méthode spécifique, le constructeur, est automatiquement invoquée afin de configurer les propriétés de l’instance.

L’instanciation d’une classe expliquée

En JavaScript, l’instanciation d’une classe se réalise en utilisant le mot-clé `new` suivi du nom de la classe. Prenons l’exemple de l’instanciation de la classe `Array` :

const myArr = new Array()

Créer des classes en JavaScript

Cette section explorera la création d’une classe qui met en œuvre tous les concepts précédemment abordés dans la section terminologie. Nous procéderons par une série d’exemples, chaque nouvel exemple se basant sur les précédents.

Déclarer une classe vide

Pour déclarer une classe en JavaScript, le mot-clé `class` est utilisé, suivi du nom de la classe, puis du corps de la classe, délimité par des accolades et contenant tous ses membres.

Voici un exemple de déclaration d’une classe avec un corps vide :

class Dog {

}

On peut ensuite instancier cette classe comme suit, et afficher l’instance créée :

const pet = new Dog;
console.log(pet);

Création de propriétés publiques

Les propriétés publiques sont définies avec un identifiant et, éventuellement, une valeur initiale.

class Dog {
    name = "Roy";
    age;
}

Dans cet exemple, la propriété `name` est initialisée avec la chaîne « Roy », tandis que la propriété `age` n’a pas de valeur initiale.

const pet = new Dog();

console.log(pet.name);
console.log(pet.age);

Définition de méthodes publiques

Il est possible d’ajouter des méthodes au corps de la classe. La définition d’une méthode se fait de la même manière qu’une fonction, à l’exception de l’omission du mot-clé `function`.

class Dog {
    name = "Roy";
    age;

    walk () {
        console.log("Walking");
    }
}

L’exemple précédent définit la méthode `walk`. Chaque instance de la classe `Dog` possédera cette méthode.

const pet = new Dog();
pet.walk();

Accéder aux propriétés à partir des méthodes

L’accès aux propriétés d’un objet se fait généralement à l’aide de l’opérateur point. Par exemple, si un objet `person` possède une propriété `name`, on y accède comme ceci :

person.name

Cependant, si l’accès à une propriété se fait depuis une méthode de l’objet lui-même, on utilise le mot-clé `this` à la place du nom de l’objet. Par exemple :

this.name

Le mot-clé `this` fait référence à l’objet courant. Ainsi, pour accéder aux propriétés de la classe depuis ses méthodes, on utilisera la syntaxe `this.nom_de_la_propriété`.

Création de propriétés privées

Supposons que les propriétés `name` et `age` doivent être privées. On redéfinirait alors la classe comme suit :

class Dog {
    #name = "Roy";
    #age;

    walk () {
        console.log("Walking");
    }
}

Les propriétés privées sont identifiées par le symbole `#`. Tenter d’y accéder directement générera une erreur.

const dog = new Dog();

dog.#name

Création de méthodes Getter et Setter

Les propriétés `name` et `age` étant désormais privées, elles ne sont accessibles que via les méthodes internes de la classe.

Pour permettre au code extérieur d’accéder à ces propriétés, on définit des getters et des setters. Illustrons cela avec la propriété `name`.

class Dog {
    #name = "Roy";
    #age;

    get name () {
        return this.#name;
    }

    set name (value) {
        this.#name = value;
    }

    walk () {
        console.log("Walking");
    }
}

Avec la classe définie ci-dessus, on peut modifier et afficher la propriété `name` comme suit :

const pet = new Dog();

// Modification du nom
pet.name = "Rex";

// Récupération du nom
console.log(pet.name);

Création de méthodes privées

À l’instar des propriétés privées, les méthodes privées sont précédées du symbole `#`. Voici un exemple de déclaration de méthodes privées :

class Dog {
    #name = "Roy";
    #age;

    get name () {
        return this.#name;
    }

    set name (value) {
        this.#name = value;
    }

    #increaseAge() {
        this.#age ++;
    }

    #decreaseAge () {
        this.#age --;
    }

    walk () {
        console.log("Walking");
    }
}

Tenter d’accéder à ces méthodes depuis l’extérieur de la classe résultera en une erreur.

const pet = new Dog();
pet.#increaseAge();

Création d’une méthode constructeur

La méthode constructeur est automatiquement invoquée à chaque instanciation d’une classe. Elle est généralement utilisée pour initialiser les propriétés. Dans cet exemple, nous initialiserons l’âge et le nom à partir des arguments fournis lors de l’instanciation.

class Dog {
    #name;
    #age;

    constructor (name = "Dog", age = 0) {
        this.#name = name;
        this.#age = age;
    }

    get name () {
        return this.#name;
    }

    set name (value) {
        this.#name = value;
    }

    #increaseAge() {
        this.#age ++;
    }

    #decreaseAge () {
        this.#age --;
    }

    walk () {
        console.log("Walking");
    }
}

Lors de l’instanciation de la classe, on peut alors spécifier un nom et un âge :

const pet = new Dog('Roy', 3);
console.log(pet.name);

Création de propriétés et de méthodes statiques

Les membres statiques sont accessibles sans instanciation préalable de la classe. L’exemple suivant illustre la création d’une propriété et d’une méthode statiques.

class Dog {
    #name;
    #age;
    static genus = "Canis";

    constructor (name = "Dog", age = 0) {
        this.#name = name;
        this.#age = age;
    }

    static bark() {
        console.log("Woof");
    }

    get name () {
        return this.#name;
    }

    set name (value) {
        this.#name = value;
    }

    #increaseAge() {
        this.#age ++;
    }

    #decreaseAge () {
        this.#age --;
    }

    walk () {
        console.log("Walking");
    }
}

On peut maintenant accéder à la propriété et à la méthode statiques directement via la classe, sans créer d’instance :

console.log(Dog.genus);
Dog.bark();

Héritage

L’héritage permet à une classe de récupérer les propriétés d’une autre classe. La classe qui hérite est appelée superclasse, tandis que la classe dont elle hérite est la classe de base ou sous-classe.

Pour définir une superclasse en JavaScript, le mot-clé `extends` est utilisé. L’exemple suivant montre comment hériter de la classe `Dog`.

class Rottweiler extends Dog {
    constructor (name, age) {
        super(name, age);
        this.breed = 'rottweiler';
    }
}

Le code est en grande partie identique, à l’exception de l’appel à la fonction `super` dans le constructeur. Le mot-clé `super` fait référence au constructeur de la classe de base. Dans notre superclasse, nous appelons donc le constructeur de la classe `Dog` en lui transmettant le nom et l’âge.

const myPet = new Rottweiler();
console.log(myPet);

Conclusion

Cet article a couvert l’essentiel des classes en JavaScript. Nous avons exploré leur nature, les membres qu’elles peuvent contenir et les différentes classifications de ces membres. Le tout a été illustré à travers des exemples concrets.

Pour approfondir vos connaissances, vous pourriez ensuite consulter des questions d’entretien liées à la programmation orientée objet.