From bf8e099b9c8b3c60d60b3712b4fc97b052c39887 Mon Sep 17 00:00:00 2001 From: julieng Date: Tue, 3 Aug 2021 08:03:23 +0200 Subject: convert content to md --- files/fr/web/javascript/reference/classes/index.md | 303 ++++++++++----------- 1 file changed, 151 insertions(+), 152 deletions(-) (limited to 'files/fr/web/javascript/reference/classes/index.md') diff --git a/files/fr/web/javascript/reference/classes/index.md b/files/fr/web/javascript/reference/classes/index.md index 33721a3faa..2808bc1d39 100644 --- a/files/fr/web/javascript/reference/classes/index.md +++ b/files/fr/web/javascript/reference/classes/index.md @@ -9,39 +9,43 @@ tags: - Reference translation_of: Web/JavaScript/Reference/Classes --- -
{{JsSidebar("Classes")}}
+{{JsSidebar("Classes")}} -

Les classes JavaScript ont été introduites avec ECMAScript 2015. Elles sont un « sucre syntaxique » par rapport à l'héritage prototypal. En effet, cette syntaxe n'introduit pas un nouveau modèle d'héritage dans JavaScript ! Elle fournit uniquement une syntaxe plus simple pour créer des objets et manipuler l'héritage.

+Les classes JavaScript ont été introduites avec ECMAScript 2015. Elles sont un « sucre syntaxique » par rapport à l'héritage prototypal. En effet, cette syntaxe n'introduit pas un nouveau modèle d'héritage dans JavaScript ! Elle fournit uniquement une syntaxe plus simple pour créer des objets et manipuler l'héritage. -

Définir des classes

+## Définir des classes -

En réalité, les classes sont juste des fonctions spéciales. Ainsi, les classes sont définies de la même façon que les fonctions : par déclaration, ou par expression.

+En réalité, les classes sont juste des [fonctions](/fr/docs/Web/JavaScript/Reference/Fonctions) spéciales. Ainsi, les classes sont définies de la même façon que les fonctions : par déclaration, ou par expression. -

Les déclarations de classes

+### Les déclarations de classes -

Pour utiliser une déclaration de classe simple, on utilisera le mot-clé class, suivi par le nom de la classe que l'on déclare (ici « Rectangle »).

+Pour utiliser une déclaration de classe simple, on utilisera le mot-clé `class`, suivi par le nom de la classe que l'on déclare (ici « Rectangle »). -
class Rectangle {
+```js
+class Rectangle {
   constructor(hauteur, largeur) {
     this.hauteur = hauteur;
     this.largeur = largeur;
   }
-}
+} +``` -

Remontée des déclarations (hoisting)

+#### Remontée des déclarations (_hoisting_) -

Les déclarations de fonctions sont remontées dans le code. En revanche, ce n'est pas le cas pour les déclarations de classes. Ainsi, il est nécessaire de déclarer la classe avant de l'instancier. Dans le cas contraire, on obtient une {{jsxref("ReferenceError")}} :

+[Les déclarations de fonctions](/fr/docs/Web/JavaScript/Reference/Instructions/function) sont remontées dans le code. En revanche, ce n'est pas le cas pour les déclarations de classes. Ainsi, il est nécessaire de déclarer la classe avant de l'instancier. Dans le cas contraire, on obtient une {{jsxref("ReferenceError")}} : -
const p = new Rectangle(); // ReferenceError
+```js example-bad
+const p = new Rectangle(); // ReferenceError
 
 class Rectangle {}
-
+``` -

Les expressions de classes

+### Les expressions de classes -

Il est possible d'utiliser des expressions de classes, nommées ou anonymes. Si on utilise un nom dans l'expression, ce nom ne sera accessible que depuis le corps de la classe via la propriété {{jsxref("Function.name", "name")}} (cette valeur ne sera pas directement accessible pour les instances).

+Il est possible d'utiliser des expressions de classes, nommées ou anonymes. Si on utilise un nom dans l'expression, ce nom ne sera accessible que depuis le corps de la classe via la propriété {{jsxref("Function.name", "name")}} (cette valeur ne sera pas directement accessible pour les instances). -
// anonyme
+```js
+// anonyme
 let Rectangle = class {
   constructor(hauteur, largeur) {
     this.hauteur = hauteur;
@@ -56,31 +60,30 @@ let Rectangle = class Rectangle {
     this.largeur = largeur;
   }
 };
-
+``` -
-

Note : Les mêmes règles s'appliquent aux expressions de classes en ce qui concerne la remontée (hoisting) des classes (cf. le paragraphe précédent sur les remontées des déclarations de classe).

-
+> **Note :** Les mêmes règles s'appliquent aux expressions de classes en ce qui concerne la remontée (_hoisting_) des classes (cf. le paragraphe précédent sur les remontées des déclarations de classe). -

Corps d'une classe et définition des méthodes

+## Corps d'une classe et définition des méthodes -

Le corps d'une classe est la partie contenue entre les accolades. C'est dans cette partie que l'on définit les propriétés d'une classe comme ses méthodes et son constructeur.

+Le corps d'une classe est la partie contenue entre les accolades. C'est dans cette partie que l'on définit les propriétés d'une classe comme ses méthodes et son constructeur. -

Mode strict

+### Mode strict -

Le corps des classes, pour les expressions et pour les déclarations de classes, est exécuté en mode strict (autrement dit, le constructeur, les méthodes statiques, le prototype, les accesseurs (getters) et mutateurs (setters) sont exécutés en mode strict).

+Le corps des classes, pour les expressions et pour les déclarations de classes, est exécuté en [mode strict](/fr/docs/Web/JavaScript/Reference/Strict_mode) (autrement dit, le constructeur, les méthodes statiques, le prototype, les accesseurs (_getters_) et mutateurs (_setters_) sont exécutés en mode strict). -

Constructeur

+### Constructeur -

La méthode constructor est une méthode spéciale qui permet de créer et d'initialiser les objet créés avec une classe. Il ne peut y avoir qu'une seule méthode avec le nom "constructor" pour une classe donnée. Si la classe contient plusieurs occurences d'une méthode constructor, cela provoquera une exception {{jsxref("SyntaxError")}}.

+La méthode [`constructor`](/fr/docs/Web/JavaScript/Reference/Classes/constructor) est une méthode spéciale qui permet de créer et d'initialiser les objet créés avec une classe. Il ne peut y avoir qu'une seule méthode avec le nom "constructor" pour une classe donnée. Si la classe contient plusieurs occurences d'une méthode `constructor`, cela provoquera une exception {{jsxref("SyntaxError")}}. -

Le constructeur ainsi déclaré peut utiliser le mot-clé super afin d'appeler le constructeur de la classe parente.

+Le constructeur ainsi déclaré peut utiliser le mot-clé `super` afin d'appeler le constructeur de la classe parente. -

Méthodes de prototype

+### Méthodes de prototype -

Voir aussi les définitions de méthode.

+Voir aussi les définitions de méthode. -
class Rectangle {
+```js
+class Rectangle {
   constructor(hauteur, largeur) {
     this.hauteur = hauteur;
     this.largeur = largeur;
@@ -97,13 +100,15 @@ let Rectangle = class Rectangle {
 
 const carré = new Rectangle(10, 10);
 
-console.log(carré.area);
+console.log(carré.area); +``` -

Méthodes statiques

+### Méthodes statiques -

Le mot-clé static permet de définir une méthode statique pour une classe. Les méthodes statiques sont appelées par rapport à la classe entière et non par rapport à une instance donnée (ces méthodes ne peuvent pas être appelées « depuis » une instance). Ces méthodes sont généralement utilisées sous formes d'utilitaires au sein d'applications.

+Le mot-clé [`static`](/fr/docs/Web/JavaScript/Reference/Classes/static) permet de définir une méthode statique pour une classe. Les méthodes statiques sont appelées par rapport à la classe entière et non par rapport à une [instance](/fr/docs/Web/JavaScript/Introduction_à_JavaScript_orienté_objet#L'instance) donnée (ces méthodes ne peuvent pas être appelées « depuis » une instance). Ces méthodes sont généralement utilisées sous formes d'utilitaires au sein d'applications. -
class Point {
+```js
+class Point {
   constructor(x, y) {
     this.x = x;
     this.y = y;
@@ -119,13 +124,15 @@ console.log(carré.area);
const p1 = new Point(5, 5); const p2 = new Point(10, 10); -console.log(Point.distance(p1, p2)); +console.log(Point.distance(p1, p2)); +``` -

Gestion de this pour le prototype et les méthodes statiques

+### Gestion de `this` pour le prototype et les méthodes statiques -

Lorsqu'une méthode statique ou une méthode liée au prototype est appelée sans valeur this, celle-ci vaudra undefined au sein de la fonction. Il n'y aura pas d'autodétermination de this (autoboxing en anglais). On aura le même résultat si on invoque ces fonctions dans du code non-strict car les fonctions liées aux classes sont exécutées en mode strict.

+Lorsqu'une méthode statique ou une méthode liée au prototype est appelée sans valeur `this`, celle-ci vaudra `undefined` au sein de la fonction. Il n'y aura pas d'autodétermination de `this` (_autoboxing_ en anglais). On aura le même résultat si on invoque ces fonctions dans du code non-strict car les fonctions liées aux classes sont exécutées en mode strict. -
class Animal {
+```js
+class Animal {
   crie() {
     return this;
   }
@@ -141,13 +148,15 @@ crie(); // undefined
 
 Animal.mange(); // class Animal
 let mange = Animal.mange;
-mange(); // undefined
+mange(); // undefined +``` -

Si on écrit le code avec des fonctions traditionnelles plutôt qu'avec des classes et qu'on utilise le mode non-strict, l'autodétermination de this sera faite en fonction du contexte dans lequel la fonction a été appelée. Si la valeur initiale est undefined, this correspondra à l'objet global.

+Si on écrit le code avec des fonctions traditionnelles plutôt qu'avec des classes et qu'on utilise le mode non-strict, l'autodétermination de `this` sera faite en fonction du contexte dans lequel la fonction a été appelée. Si la valeur initiale est `undefined`, `this` correspondra à l'objet global. -

L'autodétermination de this n'a pas lieu en mode strict, la valeur this est passée telle quelle.

+L'autodétermination de `this` n'a pas lieu en mode strict, la valeur `this` est passée telle quelle. -
function Animal() { }
+```js
+function Animal() { }
 
 Animal.prototype.crie = function() {
   return this;
@@ -163,75 +172,80 @@ crie(); // l'objet global
 
 let mange = Animal.mange;
 mange(); // l'objet global
-
+``` -

Propriétés des instances

+### Propriétés des instances -

Les propriétés des instances doivent être définies dans les méthodes de la classe :

+Les propriétés des instances doivent être définies dans les méthodes de la classe : -
class Rectangle {
+```js
+class Rectangle {
   constructor(hauteur, largeur) {
     this.hauteur = hauteur;
     this.largeur = largeur;
   }
-}
+} +``` -

Les propriétés statiques ou les données relatives au prototype doivent être définies en dehors de la déclaration comportant le corps de la classe :

+Les propriétés statiques ou les données relatives au prototype doivent être définies en dehors de la déclaration comportant le corps de la classe : -
Rectangle.largeurStatique = 20;
-Rectangle.prototype.largeurProto = 25;
+```js +Rectangle.largeurStatique = 20; +Rectangle.prototype.largeurProto = 25; +``` -

Déclarations de champs

+### Déclarations de champs -

{{SeeCompatTable}}

+{{SeeCompatTable}} -
-

Attention : Les déclarations de champs publics et privés sont une fonctionnalité expérimentale actuellement proposée pour être intégrée dans le standard ECMAScript. Elle n'est pas implémentée par la majorité des navigateurs mais on peut émuler cette fonctionnalité en utilisant un système de compilation tel que Babel.

-
+> **Attention :** Les déclarations de champs publics et privés sont une [fonctionnalité expérimentale actuellement proposée pour être intégrée dans le standard ECMAScript](https://github.com/tc39/proposal-class-fields). Elle n'est pas implémentée par la majorité des navigateurs mais on peut émuler cette fonctionnalité en utilisant un système de compilation tel que [Babel](https://babeljs.io/). -

Déclarations de champs publics

+#### Déclarations de champs publics -

En utilisant la syntaxe pour la déclaration des champs, on peut réécrire l'exemple précédent de la façon suivante :

+En utilisant la syntaxe pour la déclaration des champs, on peut réécrire l'exemple précédent de la façon suivante : -
class Rectangle {
+```js
+class Rectangle {
   hauteur = 0;
   largeur;
   constructor(hauteur, largeur) {
     this.hauteur = hauteur;
     this.largeur = largeur;
   }
-}
+} +``` -

En déclarant les champs en préalable, il est plus facile de comprendre la classe dans son ensemble. De plus, on s'assure que les champs soient toujours présents.

+En déclarant les champs en préalable, il est plus facile de comprendre la classe dans son ensemble. De plus, on s'assure que les champs soient toujours présents. -

Comme on peut le voir dans cet exemple, les champs peuvent éventuellement être déclarés avec une valeur par défaut.

+Comme on peut le voir dans cet exemple, les champs peuvent éventuellement être déclarés avec une valeur par défaut. -

Déclarations de champs privés

+#### Déclarations de champs privés -

En utilisant des champs privés, on peut revoir la définition de la façon suivante :

+En utilisant des champs privés, on peut revoir la définition de la façon suivante : -
class Rectangle {
+```js
+class Rectangle {
   #hauteur = 0;
   #largeur;
   constructor(hauteur, largeur){
     this.#hauteur = hauteur;
     this.#largeur = largeur;
   }
-}
+} +``` -

Si on utilise les champs privés hors de la classe, cela génèrera une erreur. Ces champs ne peuvent être lus ou modifiés que depuis le corps de la classe. En évitant d'exposer des éléments à l'extérieur, on s'assure que les portions de code qui consomment cette classe n'utilise pas ses détails internes et on peut alors maintenir la classe dans son ensemble et modifier les détails internes si besoin.

+Si on utilise les champs privés hors de la classe, cela génèrera une erreur. Ces champs ne peuvent être lus ou modifiés que depuis le corps de la classe. En évitant d'exposer des éléments à l'extérieur, on s'assure que les portions de code qui consomment cette classe n'utilise pas ses détails internes et on peut alors maintenir la classe dans son ensemble et modifier les détails internes si besoin. -
-

Note : Les champs privés doivent nécessairement être déclarés en premier dans les déclarations de champ.

-
+> **Note :** Les champs privés doivent nécessairement être déclarés en premier dans les déclarations de champ. -

Il n'est pas possible de créer des champs privés a posteriori au moment où on leur affecterait une valeur. Autrement dit, il est possible de déclarer une variable normale au moment voulu lorsqu'on lui affecte une valeur tandis que pour les champs privés, ces derniers doivent être déclarés (éventuellement initialisés) en amont, au début du corps de la classe.

+Il n'est pas possible de créer des champs privés _a posteriori_ au moment où on leur affecterait une valeur. Autrement dit, il est possible de déclarer une variable normale au moment voulu lorsqu'on lui affecte une valeur tandis que pour les champs privés, ces derniers doivent être déclarés (éventuellement initialisés) en amont, au début du corps de la classe. -

Créer une sous-classe avec extends

+## Créer une sous-classe avec `extends` -

Le mot-clé extends, utilisé dans les déclarations ou les expressions de classes, permet de créer une classe qui hérite d'une autre classe (on parle aussi de « sous-classe » ou de « classe-fille »).

+Le mot-clé [`extends`](/fr/docs/Web/JavaScript/Reference/Classes/extends), utilisé dans les déclarations ou les expressions de classes, permet de créer une classe qui hérite d'une autre classe (on parle aussi de « sous-classe » ou de « classe-fille »). -
class Animal {
+```js
+class Animal {
   constructor(nom) {
     this.nom = nom;
   }
@@ -248,13 +262,15 @@ class Chien extends Animal {
   parle() {
     console.log(`${this.nom} aboie.`);
   }
-}
+} +``` -

Si on déclare un constructeur dans une classe fille, on doit utiliser super() avant this.

+Si on déclare un constructeur dans une classe fille, on doit utiliser `super()` avant `this`. -

On peut également étendre des classes plus traditionnelles basées sur des constructeurs fonctionnels :

+On peut également étendre des classes plus _traditionnelles_ basées sur des constructeurs fonctionnels : -
function Animal (nom) {
+```js
+function Animal (nom) {
   this.nom = nom;
 }
 Animal.prototype.crie = function () {
@@ -271,11 +287,13 @@ class Chien extends Animal {
 let c = new Chien('Ida');
 c.crie();
 // Ida fait du bruit.
-// Ida aboie.
+// Ida aboie. +``` -

En revanche, les classes ne permettent pas d'étendre des objets classiques non-constructibles. Si on souhaite créer un lien d'héritage en un objet et une classe, on utilisera {{jsxref("Object.setPrototypeOf()")}} :

+En revanche, les classes ne permettent pas d'étendre des objets classiques non-constructibles. Si on souhaite créer un lien d'héritage en un objet et une classe, on utilisera {{jsxref("Object.setPrototypeOf()")}} : -
const Animal = {
+```js
+const Animal = {
   crie() {
     console.log(`${this.nom} fait du bruit.`);
   }
@@ -295,30 +313,34 @@ Object.setPrototypeOf(Chien.prototype, Animal);
 let d = new Chien('Ida');
 d.crie();
 // Ida fait du bruit
-// Ida aboie.
+// Ida aboie. +``` -

Le symbole species

+## Le symbole `species` -

Lorsqu'on souhaite renvoyer des objets {{jsxref("Array")}} avec une sous-classe MonArray, on peut utiliser symbole species pour surcharger le constructeur par défaut.

+Lorsqu'on souhaite renvoyer des objets {{jsxref("Array")}} avec une sous-classe `MonArray`, on peut utiliser symbole `species` pour surcharger le constructeur par défaut. -

Par exemple, si, lorsqu'on utilise des méthodes comme {{jsxref("Array.map","map()")}} qui renvoient le constructeur par défaut et qu'on veut qu'elles renvoient Array plutôt que MonArray, on utilisera {{jsxref("Symbol.species")}} :

+Par exemple, si, lorsqu'on utilise des méthodes comme {{jsxref("Array.map","map()")}} qui renvoient le constructeur par défaut et qu'on veut qu'elles renvoient `Array` plutôt que `MonArray`, on utilisera {{jsxref("Symbol.species")}} : -
class MonArray extends Array {
+```js
+class MonArray extends Array {
   // On surcharge species
   // avec le constructeur Array du parent
   static get [Symbol.species]() { return Array; }
 }
 let a = new MonArray(1,2,3);
-let mapped = a.map(x => x * x);
+let mapped = a.map(x => x * x);
 
 console.log(mapped instanceof MonArray); // false
-console.log(mapped instanceof Array);    // true
+console.log(mapped instanceof Array); // true +``` -

Utiliser super pour la classe parente

+## Utiliser super pour la classe parente -

Le mot-clé super est utilisé pour appeler les fonctions rattachées à un objet parent.

+Le mot-clé [`super`](/fr/docs/Web/JavaScript/Reference/Opérateurs/super) est utilisé pour appeler les fonctions rattachées à un objet parent. -
class Chat {
+```js
+class Chat {
   constructor(nom) {
     this.nom = nom;
   }
@@ -334,78 +356,55 @@ class Lion extends Chat {
     console.log(`${this.nom} rugit.`);
   }
 }
-
+``` -

Les mix-ins

+## Les _mix-ins_ -

Les sous-classes abstraites ou mix-ins sont des modèles (templates) pour des classes. Une classe ECMAScript ne peut avoir qu'une seule classe parente et il n'est donc pas possible, par exemple, d'hériter de plusieurs classes dont une classe abstraite. La fonctionnalité dont on souhaite disposer doit être fournie par la classe parente.

+Les sous-classes abstraites ou _mix-ins_ sont des modèles (_templates_) pour des classes. Une classe ECMAScript ne peut avoir qu'une seule classe parente et il n'est donc pas possible, par exemple, d'hériter de plusieurs classes dont une classe abstraite. La fonctionnalité dont on souhaite disposer doit être fournie par la classe parente. -

Une fonction peut prendre une classe parente en entrée et renvoyer une classe fille qui étend cette classe parente. Cela peut permettre d'émuler les mix-ins avec ECMAScript.

+Une fonction peut prendre une classe parente en entrée et renvoyer une classe fille qui étend cette classe parente. Cela peut permettre d'émuler les _mix-ins_ avec ECMAScript. -
let calculetteMixin = Base => class extends Base {
+```js
+let calculetteMixin = Base => class extends Base {
   calc() { }
 };
 
-let aleatoireMixin = Base => class extends Base {
+let aleatoireMixin = Base => class extends Base {
   randomiseur() { }
 };
-
+``` -

Une classe utilisant ces mix-ins peut alors être écrite de cette façon :

+Une classe utilisant ces _mix-ins_ peut alors être écrite de cette façon : -
class Toto { }
+```js
+class Toto { }
 class Truc extends calculetteMixin(aleatoireMixin(Toto)) { }
-
- -

Spécifications

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpécificationÉtatCommentaires
{{SpecName('ES2015', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ES2015')}}Définition initiale.
{{SpecName('ES2016', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ES2016')}}
{{SpecName('ES2017', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ES2017')}}
{{SpecName('ESDraft', '#sec-class-definitions', 'Class definitions')}}{{Spec2('ESDraft')}}
- -

Compatibilité des navigateurs

- -

{{Compat("javascript.classes")}}

- -

Utilisation via l'éditeur multiligne dans Firefox

- -

Une classe ne peut pas être redéfinie. Si vous testez votre code via l'éditeur multiligne JavaScript de Firefox (Outils > Développement web > Editeur multiligne JavaScript) et que vous exécutez à plusieurs reprises votre code avec la définition d'une classe, vous obtiendrez une exception SyntaxError : redeclaration of let <class-name>.

- -

Pour relancer une définition, il faut utiliser le menu Exécuter > Recharger et exécuter. À ce sujet, voir le bug {{bug("1428672")}}.

- -

Voir aussi

- - +``` + +## Spécifications + +| Spécification | État | Commentaires | +| -------------------------------------------------------------------------------------------- | ---------------------------- | -------------------- | +| {{SpecName('ES2015', '#sec-class-definitions', 'Class definitions')}} | {{Spec2('ES2015')}} | Définition initiale. | +| {{SpecName('ES2016', '#sec-class-definitions', 'Class definitions')}} | {{Spec2('ES2016')}} | | +| {{SpecName('ES2017', '#sec-class-definitions', 'Class definitions')}} | {{Spec2('ES2017')}} | | +| {{SpecName('ESDraft', '#sec-class-definitions', 'Class definitions')}} | {{Spec2('ESDraft')}} | | + +## Compatibilité des navigateurs + +{{Compat("javascript.classes")}} + +## Utilisation via l'éditeur multiligne dans Firefox + +Une classe ne peut pas être redéfinie. Si vous testez votre code via l'éditeur multiligne JavaScript de Firefox (Outils > Développement web > Editeur multiligne JavaScript) et que vous exécutez à plusieurs reprises votre code avec la définition d'une classe, vous obtiendrez une exception SyntaxError : _redeclaration of let \_. + +Pour relancer une définition, il faut utiliser le menu Exécuter > Recharger et exécuter. À ce sujet, voir le bug {{bug("1428672")}}. + +## Voir aussi + +- [Les fonctions](/fr/docs/Web/JavaScript/Reference/Fonctions) +- {{jsxref("Instructions/class", "Les déclarations de classes","",1)}} +- {{jsxref("Opérateurs/class", "Les expressions de classes","",1)}} +- {{jsxref("Opérateurs/super", "super")}} +- [Billet sur les classes (traduction en français)](https://tech.mozfr.org/post/2015/07/29/ES6-en-details-%3A-les-classes) +- [Champs publics et privés pour les classes (proposition de niveau 3)](https://github.com/tc39/proposal-class-fields) -- cgit v1.2.3-54-g00ecf