En JavaScript, chaque objet est à la fois une instance et une classe. Pour faire l'héritage, vous pouvez utiliser n'importe quelle instance d'objet comme prototype.
En Python, C ++, etc., il existe des classes et des instances, en tant que concepts séparés. Pour faire l'héritage, vous devez utiliser la classe de base pour créer une nouvelle classe, qui peut ensuite être utilisée pour produire des instances dérivées.
Pourquoi JavaScript est-il allé dans cette direction (orientation objet basée sur un prototype)? quels sont les avantages (et inconvénients) de l'OO basé sur un prototype par rapport à l'OO traditionnel basé sur une classe?
javascript
oop
inheritance
prototype-programming
Stefano Borini
la source
la source
GEB
?Réponses:
Il y a une centaine de problèmes de terminologie ici, principalement construits autour de quelqu'un (pas vous) essayant de faire sonner son idée comme The Best.
Tous les langages orientés objet doivent pouvoir traiter plusieurs concepts:
Maintenant, en ce qui concerne la comparaison:
La première chose est toute la question "classe" vs "prototype". L'idée a commencé à l'origine dans Simula, où avec une méthode basée sur les classes, chaque classe représentait un ensemble d'objets qui partageaient le même espace d'état (lire "valeurs possibles") et les mêmes opérations, formant ainsi une classe d'équivalence. Si vous regardez en arrière Smalltalk, puisque vous pouvez ouvrir une classe et ajouter des méthodes, c'est en fait la même chose que ce que vous pouvez faire en Javascript.
Plus tard, les langages OO voulaient pouvoir utiliser la vérification de type statique, nous avons donc eu la notion d'un ensemble de classes fixe au moment de la compilation. Dans la version open-class, vous aviez plus de flexibilité; dans la version la plus récente, vous aviez la possibilité de vérifier certains types d'exactitude sur le compilateur qui auraient autrement nécessité des tests.
Dans un langage "basé sur les classes", cette copie a lieu au moment de la compilation. Dans un langage prototype, les opérations sont stockées dans la structure de données prototype, qui est copiée et modifiée au moment de l'exécution. De manière abstraite, cependant, une classe est toujours la classe d'équivalence de tous les objets qui partagent le même espace d'état et les mêmes méthodes. Lorsque vous ajoutez une méthode au prototype, vous créez effectivement un élément d'une nouvelle classe d'équivalence.
Maintenant, pourquoi faire ça? principalement parce qu'il permet un mécanisme simple, logique et élégant au moment de l'exécution. maintenant, pour créer un nouvel objet, ou pour créer une nouvelle classe, il vous suffit d'effectuer une copie complète, en copiant toutes les données et la structure de données du prototype. Vous obtenez alors l'héritage et le polymorphisme plus ou moins gratuitement: la recherche de méthode consiste toujours à demander à un dictionnaire une implémentation de méthode par nom.
La raison qui a abouti au script Javascript / ECMA est essentiellement que lorsque nous avons commencé avec cela il y a 10 ans, nous avions affaire à des ordinateurs beaucoup moins puissants et à des navigateurs beaucoup moins sophistiqués. Le choix de la méthode basée sur le prototype signifiait que l'interpréteur pouvait être très simple tout en préservant les propriétés souhaitables de l'orientation des objets.
la source
Une comparaison, qui est légèrement biaisée vers l'approche basée sur les prototypes, peut être trouvée dans l'article Self: The Power of Simplicity . Le document présente les arguments suivants en faveur des prototypes:
Self est probablement le premier langage à implémenter des prototypes (il a également lancé d'autres technologies intéressantes comme JIT, qui a ensuite fait son chemin dans la JVM), donc la lecture des autres papiers Self devrait également être instructive.
la source
point
est une instance de classePoint
, qui est une instance de métaclassestandard-class
, qui est une instance d'elle-même, ad finitum.Vous devriez consulter un excellent livre sur JavaScript par Douglas Crockford . Il fournit une très bonne explication de certaines des décisions de conception prises par les créateurs JavaScript.
L'un des aspects de conception importants de JavaScript est son système d'héritage prototypique. Les objets sont des citoyens de première classe en JavaScript, à tel point que les fonctions régulières sont également implémentées en tant qu'objets (objet 'Function' pour être précis). À mon avis, lorsqu'il a été initialement conçu pour fonctionner dans un navigateur, il devait être utilisé pour créer de nombreux objets singleton. Dans le navigateur DOM, vous trouvez cette fenêtre, documentez etc. tous les objets singleton. De plus, JavaScript est un langage dynamique typé de manière lâche (contrairement à Python qui est un langage dynamique fortement typé), par conséquent, un concept d'extension d'objet a été implémenté grâce à l'utilisation de la propriété `` prototype ''.
Je pense donc qu'il existe des avantages pour les OO basés sur des prototypes, implémentés en JavaScript:
Voici certains des inconvénients de l'OO prototypique:
la source