Guide JavaScript 1.5:Langages basés sur les classes et langages basés sur les prototypes
Un article de MDC.
Sommaire |
[modifier] Langages basés sur les classes et langages basés sur les prototypes
Les langages orientés objet basés sur les classes, comme Java et C++ sont fondés sur le concept de deux entités distinctes : les classes et les instances.
- Une classe définit toutes les propriétés (si l'on considère les méthodes et les champs en Java, ou les membres en C++, comme étant des propriétés) qui caractérisent un certain ensemble d'objets. Une classe est quelque chose d'abstrait, plutôt qu'un élément particulier de l'ensemble d'objets qu'elle décrit. Par exemple, une classe Employé pourrait représenter l'ensemble de tous les employés.
- Une instance, d'autre part, est l'instanciation d'une classe ; c'est-à-dire l'un de ses membres. Par exemple,
Virginiepourrait être une instance de la classeEmployé, représentant un individu particulier en tant qu'employé. Une instance possède exactement les propriétés de sa classe parente (ni plus, ni moins).
Un langage basé sur les prototypes, comme JavaScript, ne fait pas cette distinction : il y a simplement des objets. Un tel langage possède la notion d'objet prototype, un objet utilisé comme modèle depuis lequel on obtient les propriétés initiales pour un nouvel objet. Tout objet peut spécifier ses propres propriétés, que ce soit à sa création ou à l'exécution. De plus, tout objet peut être associé au prototype d'un autre objet, ce qui permet à ce second objet de partager toutes les propriétés du premier.
[modifier] Définition d'une classe
Dans les langages basés sur les classes, on définit une classe dans une définition séparée. Dans celle-ci, on peut spécifier des méthodes particulières appelées constructeurs pour créer des instances de la classe. Un constructeur peut spécifier des valeurs initiales pour les propriétés de l'instance et exécuter d'autres instructions nécessaires au moment de la création de l'objet. On utilise l'opérateur new en association avec le constructeur pour créer de nouvelles instances de la classe.
JavaScript suit un modèle similaire, mais ne sépare pas la définition d'une classe du constructeur. À la place, on définit une fonction constructeur pour créer des objets avec un jeu initial de propriétés et de valeurs. Toute fonction JavaScript peut être utilisée comme un constructeur. On utilise l'opérateur new avec un constructeur pour créer un nouvel objet.
[modifier] Sous-classes et héritage
Dans un langage basé sur les classes, on crée une hiérarchie de classes au travers des définitions de classes. Dans une définition, on peut spécifier que la classe est une sous-classe d'une classe déjà existante. La sous-classe hérite de toutes les propriétés de la superclasse et peut également ajouter de nouvelles propriétés ou modifier celles qui ont été héritées. Par exemple, supposons que la classe Employé comprenne uniquement les propriétés nom et département, et que Manager soit une sous-classe d'Employé qui ajoute la propriété supervise. Dans ce cas, une instance de la classe Manager disposerait des trois propriétés : nom, département et supervise.
JavaScript implémente l'héritage en permettant d'associer un objet prototype avec n'importe quelle fonction constructeur. Ainsi, on peut créer exactement le même exemple Employé - Manager, mais avec une terminologie légèrement différente. Tout d'abord, on définit la fonction constructeur Employé, en spécifiant les propriétés nom et département. Ensuite, on définit la fonction constructeur Manager, en spécifiant la propriété supérieur. Finalement, on assigne un nouvel objet Employé comme prototype de la fonction constructeur Manager. À ce moment-là, lorsqu'on crée un nouvel objet Manager, il hérite des propriétés nom et département de l'objet Employé.
[modifier] Ajout et suppression de propriétés
Dans les langages basés sur la classe, typiquement, on crée une classe au moment de la compilation et on instancie ensuite des instances ou occurrences de la classe, soit au moment de la compilation soit à l'exécution. On ne peut pas changer le nombre ou le type des propriétés d'une classe après qu'elle ait été définie. En JavaScript, par contre, on peut ajouter et retirer des propriétés de n'importe quel objet à l'exécution. Si on ajoute une propriété à un objet utilisé comme prototype pour un ensemble d'objets, tous les objets pour lesquels il est prototype reçoivent également la nouvelle propriété.
[modifier] Résumé des différences
Le tableau suivant fournit un court résumé de certaines de ces différences. Le reste de ce chapitre décrit en détail l'utilisation des constructeurs et prototypes en JavaScript pour créer une hiérarchie d'objets, et compare avec la façon dont ce serait fait en Java.
| Basé sur les classes (Java) | Basé sur les prototypes (JavaScript) |
|---|---|
| Une classe et ses instances sont des entités distinctes. | Tous les objets sont des instances. |
| On définit une classe par sa définition ; on l'instancie avec une méthode constructeur. | On définit et on crée un ensemble d'objets avec des fonctions constructeur. |
On crée un objet unique avec l'opérateur new. |
Identique. |
| On construit une hiérarchie d'objets en utilisant les définitions de classes pour définir des sous-classes des classes existantes. | On construit une hiérarchie d'objets en assignant un objet comme prototype associé à une fonction constructeur. |
| L'héritage des propriétés se fait en suivant la chaîne des classes. | L'héritage des propriétés se fait en suivant la chaîne des prototypes. |
| La définition de classe spécifie toutes les propriétés de toutes les instances d'une classe. Il n'est pas possible d'ajouter des propriétés dynamiquement à l'exécution. | La fonction constructeur ou le prototype spécifie un jeu de propriétés initial. Il est possible d'ajouter ou de retirer des propriétés dynamiquement à des objets ou à tout l'ensemble d'objets. |