Les classes en Javascript (ES6) simplifié
Published: 2021-07-11 03:02:45

Pour un débutant (comme moi), la comprehension de classes en Javascript peut-être un peu difficile. Il y a beaucoup des articles à propos du sujet, mais la plupart d'eux parlent d'une position avancée, et donc supposent divers informations qui n'existent pas dans l'esprit d'un/e developper/euse débutant/e. Et surtout, elles sont en anglais. Danc cet article-là, je vais essayer de remplir ce surface vide.

Note: Le français n'est pas ma langue maternelle comme vous pouvez comprendre, donc pardonnez-moi pour les erreurs. 

Si vous pouvez lire en anglais, vous pouvez trouver cet article en anglais ici :  https://muratcanyuksel.hashnode.dev/classes-in-javascript-es6-simplified

Dans cet article, je vais premièrement présenter les classes, après je vais parler à propos des propriétés statiques (static methods) et je vais finir par parler sur extends et super mots clés.

### Les Classes
Les classes en Javascript ressemblent Object constructors. Donc, si l'on est familiar avec eux, les classes seront vraiment facile à comprendre. Parce qu'ils toujours servent à la même fonction: créer des prototypes pour qu'on peut utiliser le même code encore et encore en lieu d'en écrire manuellement. Ils ne sont que nous presentent avec des nouveaux fonctionnalités qui n'existaient dans Object constructors. Alors, sans plus tarder, on va créer un class:


```
class Bird {
constructor (name, age){
    this.name=name;
    this.age=age;
    this.canFly= true;
}
}

``` 


Donc, la classe des mots a une méthode constructor dedans. Les arguments aura le nom de notre oiseau, son âge, et s'il pourrait voler ou pas.
La méthode  constructor sera immédiatement appelée dès que l'on l'invoque via le mot-clé "new". On utilise le mot-clé "new" pour créer un instance de class. Alors, Créons une instance appelée birdLarry:

`const birdLarry= new Bird ("Larry", 4);
`

On voit que pour créer une nouvelle instance de class, on définit une variable (birdLarry), et après la marque d'équation, on écrit le mot-clé "new" suivi du nom de la classe qu'on souhaite invoquer (Bird, dans notre cas).

Alors, si l'on écrirait `birdLarry.name;` à la console, le résultat serait `"Larry"`. Si l'on écrirait `birdLarry.age;` le résultat sérait le numéro 4. Et si l'on écrirait `birdLarry.canFly;`, le résultat sérait `"true"`.

Jusqu'ici tout va bien.

Ajoutons quelques méthodes supplémentaires à la classe Bird.
```
class Bird {
constructor (name, age){
    this.name=name;
    this.age=age;
    this.canFly= true;
}
  nameAge() {
    return `${this.name} is ${this.age} years old`;
  }
}
```
On a fait quoi ici? La méthode `nameAge` donnera des informations sur l'instance Bird. Comme si l'on écrirait,
`birdLarry.nameAge();` le résultat sérait `"Larry is 2 years old."` Pourtant, super simple. Mais, si l'on voulait changer le nom de l'oiseau? Dis-donc, de Larry à Clumsy? et si l'on voulait changer le nom aussi? 

Parce que j'ai l'impression qu'un oiseau nommé Clumsy *(maladroit)* doit être assez jeune. Ajoutons les méthodes.
```
class Bird {
constructor (name, age){
    this.name=name;
    this.age=age;
    this.canFly= true;
}
  nameAge() {
    return `${this.name} is ${this.age} years old`;
  }
  setName(name) {
    this.name = name;
  }

  setAge(age) {
    this.age = age;
  }
}
```
Avec ce code nouvellement ajouté,on peut modifier le nom et l'âge de l'oiseau. Donc, si l'on écrirait `birdLarry.setName("Clumsy");` et appellerait `birdLarry.name;` le résultat sérait `"Clumsy"` depuis qu'on a modifié le nom d'origine de l'instance de class. Aussi, depuis que Clumsy doit être un peu jeune, on voudrait modifier son âge aussi en écrivant `birdLarry.setAge(2)` dans la console.Maintenant, chaque fois que l'on appele `birdLarry.age;` le résultat serait 2.

Puff, heureux que l'on ait eu fini avec ça, car ce qui vient ensuite est beaucoup plus intéressant que ces bases :)
## Les méthodes Statiques

Et si on voudrait ajouter des méthodes non pas pour les instances mais pour la classe elle-même? Eh bien, avec la fonctionnalité des classes en ES6, ce sera hyper facile! Alors, on prends les class Bird et voit c'est quoi on peut faire avec lui en utilisant les méthodes statiques( j'écris pas les métdodes supplémentaires par souci de simplicité et d'espace)
```
class Bird {
static kingdom(){
return "Animalia";
}
static kingdomSentence () {
return `Birds belong to the kingdom ${this.kingdom()}`;
}

constructor (name, age){
    this.name=name;
    this.age=age;
    this.canFly= true;
}
}
```
Wowowowow, tranquille-toi mec, que se passe-t-il ici? Alors, ce qu'on a fait était d'ajouter deux méthodes statiques: La première renvoie à quel règne biologique appartiennent les oiseaux (Animalia, car ce sont bien des animaux), et le second renvoie une phrase utilisant le royaume. On voit que j'ai utilisé le mot-clé "this" ici. C'est une partie intéressante de la méthode statique: Alors que le mot-clé "this" ferait normalement référence à l'instance de classe s'il s'agissait d'une méthode ordinaire; à l'intérieur d'une méthode statique, il réfère à la classe elle-même. Attends attends, qu'est-ce que ça veut dire? Supporte-moi un peu.

Alors, si l'on écrirait `birdLarry.kingdom()`, le résultat serait quelque chose comme `Uncaught TypeError: birdLarry.kingdom is not a function at <anonymous>:1:11` Uf. Mais pourquoi?

Comme je l'ai mentionné dans la phrase d'ouverture de cette section, les méthodes statiques fonctionnent avec la classe elle-même, pas avec ses instances. Et `birdLarry` est une instance de classe Bird. Donc, la méthode statique ne fonctionnerait pas de tout.Par contre, la méthode statique ne fonctionnerait qu'avec la classe Bird. Comme ça: `Bird.kingdom()` retournerait "Animalia". Et si l'on écrirait `Bird.kingdomSentence()` il retournerait `"Birds belong to the kingdom Animalia"`. Assez chouette eh?

Maintenant, il existe une autre façon d'écrire ces méthodes statiques. Ils sont appelés propriétés statiques. On va voir comment ils fonctionnent.

### Les propriétés statiques

Les propriétés, au fond, sont tout sauf une fonction. Ils sont des strings, numbers, booleans etc. On peut écrire les méthodes statiques ci-dessus en tant que telles:
```
class Bird {
static kingdom= "Animalia";

static kingdomSentence=`Birds belong to the kingdom ${this.kingdom}`;

constructor (name, age){
    this.name=name;
    this.age=age;
    this.canFly= true;
}
}
```
Vous voyez ce que l'on a fait là-bas? On a supprimé toutes sortes de crochets et le mot-clé return. On a également pris les crochets qui indiquent la function calling lors de l'utilisation de `this.kingdom`. Cette méthode fonctionne exactement comme ci-dessus, mais elle est plus propre. Maintenant, que se passerait-il si l'on écrirait `Bird.kingdom ()`?

Eh bien, on aurait une erreur comme celle-ci: `Uncaught TypeError: Bird.kingdom is not a function at <anonymous>:1:6`, car maintenant ce sont des propriétés, pas des fonctions! Donc, on les appellerait comme: `Bird.kingdom`; qui renverrait `"Animalia"`, et `Bird.kingdomSentence` qui renverrait `"Birds belong to the kingdom Animalia"`.

D'accord, si l'on est d'accord avec celui-ci, on va passer à la finale et à la méthode la plus pratique que entre eux.

### Extends et Super 

C'st tout bien maintenant. On peut écrire un seul morceau de code et en créer de très nombreuses instances différentes. Mais que se passe-t-il si l'on est confrontés à une situation dans laquelle on souhaite créer une autre classe presque identique à la classe Bird? Et évidemment, on ne veut pas se répéter, taper un autre morceau de code encore et encore. On ferait quoi?

Eh bien, on utiliserait le mot-clé extend pour surmonter cette difficulté ennuyeuse.

Alors, dit que on veut créer une nouvelle classe Penguin. Puisque les pingouins sont des oiseaux, ils partageraient presque toutes les propriétés avec d'autres oiseaux. Je dis presque, car less pingouins ne peuvent pas voler, et je vais pas me laisser BBC me tromper :) https://www.youtube.com/watch?v=9dfWzp7rYR4&ab_channel=BBC

Alors, avec le code suivant, la nouvelle classe Penguin prendra tout ce que la classe Bird a. Regarde au mot-clé super là-bas: Il prend le nom et les méthodes d'âge de la classe d'origine. Je me suis également assuré que `canFly` pointe vers "false" :)
```
class Penguin extends Bird {
  constructor (name,age){
      super(name,age);
      this.canFly=false;

  }
}
```
Ce qui est arrivé là maintenant? Pour voir ce qui se passe, on var créer une nouvelle instance de la classe Penguin et l'appele `coldFeet`:

`const coldFeet= new Penguin("ColdFeet", 3);`

Le nouveau Penguin, `Coldfeet` peut accéder ą tout ce que `birdLarry` peut! Si l'on écrirait `coldFeet.age`, le résultat serait 3. Si l'on écrirait `coldFeet.canFly`, le résultat serait `"false"`. Pourquoi? Evidemment, car on était d'accord que les pingouins ne peuvent pas voler, n'est-ce pas? :) Et lest autres méthodes? Par exemple, que se passerait-il si l'on écrirait `coldFeet.nameAge();`?

Ouais, le résultat serait: `"ColdFeet is 3 years old"` car, encore une fois, la classe Penguin partage tout avec la classe Bird!

L'instance Penguin partage tout avec l'instance Bird maintenant. Mais, qu'n est-il de la classe Penguin elle-même? Partagera-t-elle les mêmes méthodes statiques avec la classe Bird?

Mais si!

Dit que l'on a utilisé des propriétés statiques lors de la définitionde la classe Bird. Si l'on écrirait Penguin.kingdom, le résultat serait "Animalia".

Et si l'on écrirait `Penguin.kingdomSentence`, le résultat serait `"Birds belong to the kingdom Animalia"` (car les pingouins sont des oiseaux, mais vas-y là...)

### La Conclusion

En conclusion, voici comment les classes sont utilisées, en ce qui me concerne, en Javascript (WS6). Ils sont cool et fonctionnels. J'espère avoir pur exprimer mes pensées aussi clairement que possible. Et, pour les développerus plus expérimentés, si vous trouvez une erreur, n'hésitez pas à m'en informer! J'aimerais bien voir mes erreurs! Si vous voulez, vous pouvez me montrer les erreurs grammaticales que j'ai fait dans cet article!

Cordialement, et happy coding :)