Qu'est-ce que cela signifie que Javascript est un langage basé sur un prototype?

255

On dit que l'un des principaux avantages de Javascript est qu'il s'agit d'un langage basé sur un prototype.

Mais qu'est-ce que cela signifie que Javascript est basé sur un prototype, et pourquoi est-ce un avantage?

Jonas Pegerfalk
la source
3
Cette réponse explique tout ce que vous devez savoir sur l'héritage prototypique: stackoverflow.com/a/16872315/783743
Aadit M Shah

Réponses:

291

L'héritage prototypique est une forme de réutilisation de code orientée objet . Javascript est l'un des seuls langages orientés objet [traditionnels] à utiliser l'héritage prototypique. Presque tous les autres langages orientés objet sont classiques.

En héritage classique , le programmeur écrit une classe, qui définit un objet. Plusieurs objets peuvent être instanciés à partir de la même classe, vous avez donc du code au même endroit qui décrit plusieurs objets dans votre programme. Les classes peuvent ensuite être organisées en une hiérarchie, favorisant la réutilisation du code. Un code plus général est stocké dans une classe de niveau supérieur, dont les classes de niveau inférieur héritent. Cela signifie qu'un objet partage du code avec d'autres objets de la même classe, ainsi qu'avec ses classes parentes.

Dans la forme d' héritage prototypique , les objets héritent directement d'autres objets. Toutes les affaires concernant les cours disparaissent. Si vous voulez un objet, vous écrivez simplement un objet. Mais la réutilisation du code est toujours une chose précieuse, donc les objets peuvent être liés entre eux dans une hiérarchie. En javascript, chaque objet possède un lien secret vers l'objet qui l'a créé, formant une chaîne. Lorsqu'un objet est demandé pour une propriété qu'il n'a pas, son objet parent sera demandé ... en continu dans la chaîne jusqu'à ce que la propriété soit trouvée ou jusqu'à ce que l'objet racine soit atteint.

Chaque fonction en JavaScript (qui sont des objets eux-mêmes) a en fait un membre appelé "prototype", qui est chargé de fournir des valeurs lorsqu'un objet leur est demandé. Le fait d'avoir ce membre permet au mécanisme constructeur (par lequel les objets sont construits à partir de fonctions) de fonctionner. L'ajout d'une propriété au prototype d'un objet fonction la rendra disponible à l'objet construit, ainsi qu'à tous les objets qui en hériteront.

Les avantages

Il peut ne pas y avoir de règle stricte et rapide expliquant pourquoi l'héritage prototypique est une forme avantageuse de réutilisation de code. La réutilisation du code lui-même est avantageuse, et l'héritage prototypique est une manière sensée de s'y prendre. Vous pourriez faire valoir que l'héritage prototypique est un modèle assez simple de réutilisation de code et que le code peut être fortement réutilisé de manière directe . Mais les langues classiques sont certainement capables de le faire également.

Sidenote: @Andrew Hedges souligne que de nombreux langages prototypiques existent . Il convient de noter que ces autres existent, mais également de noter qu'aucun d'entre eux n'est proche du courant dominant. NewtonScript a semblé avoir une certaine traction pendant un certain temps, mais est mort avec sa plate-forme. Il est également possible d'étendre certains langages modernes de manière à ajouter des capacités prototypiques.

keparo
la source
9
Salut Kelly. Bien que JavaScript soit de loin le langage prototypique le plus populaire, il en existe de nombreux autres: en.wikipedia.org/wiki/Prototype-based_programming#Languages
Andrew Hedges
2
Salut Andrew. Bon point. J'aurais dû être plus clair. J'en prendrai note.
keparo
3
Veuillez lire également ceci developer.mozilla.org/en/JavaScript/Guide/…
pramodc84
1
+1 pour une excellente réponse. Un petit commentaire: pour moi, l'héritage classique semble plus "direct" que prototypique. En fait, je vois vraiment l'objet prototype comme une simple liaison (avec d'autres objets), alors que dans une POO compilée, je considère que la classe de base est "directement héritée". En tant que tels, les objets prototypiques sont enchaînés plutôt qu'hérités (l'héritage est quelque peu truqué). Des pensées?
Prisonnier ZERO
3
@ PrisonerZERO: Je dirais que l'héritage prototypique est plus direct que classique. Au lieu que l'objet B pointe vers une classe qui hérite de la classe vers laquelle pointe l'objet A, il pointe directement vers l'objet A et dit "je suis comme cet objet, sauf ...". La grande chose sur l'héritage prototypique, et la chose qui semble la plus difficile à internaliser pour la plupart des gens, c'est qu'elle ne distingue pas les instances des types. Chaque objet est à la fois un type et une instance. Les distinctions entre les deux sont artificielles et délibérées, et sont généralement un symptôme d'être coincé dans un état d'esprit orienté classe.
cHao
54

Un langage basé sur des prototypes ne fait pas la distinction entre classes et objets: il a simplement des objets. Un langage basé sur un prototype a la notion d'un objet prototypique, un objet utilisé comme modèle à partir duquel obtenir les propriétés initiales d'un nouvel objet. Tout objet peut spécifier ses propres propriétés, soit lors de sa création, soit lors de l'exécution. De plus, tout objet peut être associé en tant que prototype pour un autre objet , permettant au deuxième objet de partager les propriétés du premier objet.

Guido
la source
6
Une très bonne explication, mais un peu trompeuse avec le commentaire sur le "modèle pour les propriétés initiales". Si vous modifiez le prototype APRÈS avoir instancié un objet, cet objet reçoit toujours ces fonctions.
nickf
32

La programmation basée sur des prototypes est un style de programmation orientée objet où les classes ne sont pas présentes, et la réutilisation des comportements (ou l'héritage dans les langages basés sur les classes) est effectuée en clonant des objets existants qui servent de prototypes.

CMS
la source
Vous sentez-vous toujours de cette façon? Parce que si c'est le cas, c'est la première explication à vraiment vraiment "cliquer" solidement avec moi.
Chazt3n
11

L'avantage / l'inconvénient est que nous pouvons créer de nouveaux types d'objets au moment de l'exécution sans avoir besoin de définir des classes (code statique). Comme la plupart des fonctionnalités, il appartient au développeur de le transformer en avantage / inconvénient.

Ci-dessus est possible car les objets sont essentiellement des fonctions dans le script java (fermetures aussi).

questzen
la source
Les objets dynamiques sont un avantage du javascript, mais ils ne sont pas vraiment liés au javascript étant un langage prototypique ou fonctionnel. Dans de nombreux langages classiques, vous pouvez créer des objets dynamiques lors de l'exécution. Les fermetures sont également quelque peu indépendantes.
keparo
2
Les classes ne sont pas nécessairement un code statique - jetez un œil à Python, dans lequel les classes sont elles-mêmes des objets et sont construites à partir de métaclasses qui sont également des objets.
Tomasz Zieliński
6

Au lieu de déclarer une structure de classe, vous pouvez créer des objets du même type et ajouter à leur définition à tout moment à l'aide du prototype de l'objet. C'est plus flexible que la façon normale de faire les choses.

Greg
la source
6

Si vous utilisez simplement des objets à l'exécution au lieu d'une classe à la compilation pour créer de nouveaux objets, cela ouvre la possibilité d'étendre un objet sans en connaître les détails. Bien sûr, cela peut devenir un inconvénient assez rapidement en fonction de l'utilisation. Je ne fais aucune hypothèse sur la langue ici, elle s'applique donc aux langues autres que javascript qui ne sont pas aussi dynamiques.

myobject.prototype=unkownobject;
myobject.newproperty=1;

Vous pouvez obtenir l'objet à peu près n'importe où; votre propre code, du réseau, de la base de données, de la liaison externe et ainsi de suite.

Notez qu'un langage n'a pas à implémenter l'héritage de prototype comme javascript. En javascript, un objet prototype est simplement partagé, tout comme ses propriétés, parmi les héritiers. L'alternative consiste à copier toutes les propriétés du prototype vers le nouvel objet. Chaque approche a ses points forts dans différentes situations. J'aime le second plus mais ce n'est pas ce que fait javascript.

ificialidiot
la source
6

Après avoir lu toutes les réponses, voici la conclusion

1) Héritage dans lequel les objets sont hérités directement des autres objets

2) Qui n'utilise pas de classes

3) Aussi appelé programmation basée sur des instances ou programmation orientée prototype sans classe

4) La réutilisation des comportements est réalisée en clonant des objets existants qui servent de prototypes

5) L'objet utilisé comme modèle à partir du nouvel objet obtient les propriétés initiales

Sunil Garg
la source