Fonction prototype de fonction

le prototype propriété est un objet créé par JavaScript pour chaque Une fonction() exemple. Plus précisément, il relie les instances d’objet créées avec le Nouveau mot-clé de retour à la fonction constructeur qui les a créés. Ceci est fait pour que les instances puissent partager ou hériter des méthodes et propriétés communes. Fait important, le partage se produit lors de la recherche de la propriété. Rappelez-vous dès le premier article que chaque fois que vous recherchez une propriété sur un objet, celle-ci sera recherchée sur l'objet ainsi que sur la chaîne de prototypes..

Un objet prototype est créé pour chaque fonction, que vous souhaitiez ou non utiliser cette fonction en tant que constructeur..

Dans le code suivant, je construis un tableau à partir du Tableau () constructeur, puis j'invoque le joindre() méthode.

Échantillon: sample118.html

 

le joindre() méthode n'est pas définie comme une propriété du mon tableau instance d'objet, mais en quelque sorte nous avons accès à joindre() Comme si c'était. Cette méthode est définie quelque part, mais où? Eh bien, il est défini comme une propriété de la Tableau () Propriété prototype du constructeur. Puisque joindre() introuvable dans l'instance de l'objet tableau, JavaScript recherche dans la chaîne de prototypes une méthode appelée joindre().

Ok, alors pourquoi les choses se passent-elles de cette façon? En réalité, il s’agit d’efficacité et de réutilisation. Pourquoi chaque instance de tableau créée à partir de la fonction constructeur de tableau doit-elle avoir une définition unique? joindre() méthode quand joindre() fonctionne toujours de la même manière? Il est plus logique que tous les tableaux exploitent le même joindre() fonction sans avoir à créer une nouvelle instance de la fonction pour chaque instance de tableau.

Cette efficacité dont nous parlons est tout à fait possible en raison de la prototype liaison, prototype et chaîne de recherche de prototype. Dans cet article, nous décomposons ces attributs souvent déroutants de l'héritage prototypique. Mais à vrai dire, vous feriez mieux de simplement mémoriser les mécanismes de fonctionnement de la hiérarchie des chaînes. Reportez-vous au premier article si vous avez besoin d'un rappel sur la façon dont les valeurs de propriété sont résolues..


Pourquoi se soucier de la prototype Propriété?

Vous devriez vous soucier de la prototype propriété pour quatre raisons.

Raison 1

La première raison est que la propriété prototype est utilisée par les fonctions de constructeur natives (Objet(), Tableau (), Une fonction(), etc.) pour permettre aux instances de constructeur d'hériter des propriétés et des méthodes. C'est le mécanisme que JavaScript lui-même utilise pour permettre aux instances d'objet d'hériter des propriétés et des méthodes de la fonction constructeur. prototype propriété. Si vous voulez mieux comprendre JavaScript, vous devez comprendre comment JavaScript lui-même tire parti de la prototype objet.

Raison 2

Lors de la création de fonctions de constructeur définies par l'utilisateur, vous pouvez orchestrer l'héritage de la même manière que les objets natifs JavaScript. Mais vous devez d'abord apprendre comment cela fonctionne.

Raison 3

Vous pourriez vraiment ne pas aimer l’héritage prototype ou préférer un autre schéma d’héritage d’objet, mais en réalité, vous devrez peut-être éditer ou gérer le code de quelqu'un d’autre qui pensait que l’héritage héréditaire était une prouesse. Dans ce cas, vous devez savoir comment fonctionne l'héritage de prototypes et comment il peut être répliqué par les développeurs utilisant des fonctions de constructeur personnalisées..

Raison 4

En utilisant l'héritage de prototypes, vous pouvez créer des instances d'objet efficaces qui exploitent toutes les mêmes méthodes. Comme déjà mentionné, tous les objets de tableau, qui sont des instances du Tableau () constructeur, besoin de leur propre joindre() méthodes. Toutes les instances peuvent exploiter le même joindre() méthode car la méthode est stockée dans la chaîne de prototypes.

Le prototype est standard sur tous Une fonction() Les instances

Toutes les fonctions sont créées à partir d’un Une fonction() constructeur, même si vous n'invoquez pas directement le Une fonction() constructeur (var add = new Function ('x', 'y', 'renvoyer x + z');) et utilise à la place la notation littérale (var add = fonction (x, y) retour x + z;).

Quand une instance de fonction est créée, elle reçoit toujours un prototype propriété, qui est un objet vide. Dans l'exemple suivant, nous définissons une fonction appelée myFunction, puis nous accédons à la prototype propriété qui est simplement un objet vide.

Échantillon: sample119.html

 

Assurez-vous de bien comprendre que la propriété prototype provient de la Une fonction() constructeur. Ce n’est que lorsque nous avons l’intention d’utiliser notre fonction en tant que fonction constructeur définie par l’utilisateur que la propriété prototype est exploitée, mais cela ne change pas le fait que Une fonction() constructeur donne à chaque instance une propriété prototype.


Le défaut prototype La propriété est un Objet() Objet

Tout ça prototype parler peut devenir un peu lourd. Vraiment, prototype est juste une propriété d'objet vide appelée "prototype" créée en coulisse par JavaScript et rendue disponible en invoquant le Une fonction() constructeur. Si vous deviez le faire manuellement, cela ressemblerait à ceci:

Échantillon: sample120.html

 

En fait, cet exemple de code fonctionne très bien, essentiellement en dupliquant ce que JavaScript fait déjà.

La valeur d'une propriété prototype peut être définie sur n'importe laquelle des valeurs complexes (objets) disponibles en JavaScript. JavaScript ignorera toute propriété prototype définie sur une valeur primitive.


Les instances créées à partir d'une fonction constructeur sont liées au constructeur prototype Propriété

Bien que ce ne soit qu'un objet, prototype est spécial car la chaîne de prototypes relie chaque instance à la propriété de prototype de sa fonction constructeur. Cela signifie que chaque fois qu'un objet est créé à partir d'une fonction constructeur à l'aide de la commande Nouveau mot clé (ou lorsqu'un wrapper d'objet est créé pour une valeur primitive), il ajoute un lien masqué entre l'instance d'objet créée et la propriété prototype de la fonction constructeur utilisée pour la créer. Ce lien est connu dans l'instance sous le nom __proto__ (bien qu'il ne soit exposé / pris en charge via le code que dans Firefox 2+, Safari, Chrome et Android). JavaScript relie ceci en arrière-plan lorsqu'une fonction constructeur est appelée, et c'est ce lien qui permet à la chaîne de prototypes d'être, ainsi, une chaîne. Dans l'exemple suivant, nous ajoutons une propriété au natif Tableau () constructeurs prototype, auquel nous pouvons ensuite accéder à partir d'un Tableau () exemple en utilisant le __proto__ ensemble de propriétés sur cette instance.

Échantillon: sample121.html

 

Depuis l'accès __proto__ ne fait pas partie de la norme officielle ECMA, il existe un moyen plus universel de tracer le lien d’un objet à l’objet prototype hérité, c’est-à-dire en utilisant le constructeur propriété. Ceci est démontré dans l'exemple suivant.

Échantillon: sample122.html

 

Dans cet exemple, le foo la propriété est trouvée dans l'objet prototype. Vous devez réaliser que cela n’est possible que grâce à l’association entre l’instance de Tableau () et le Tableau () objet prototype constructeur (Array.prototype). Tout simplement, myArray .__ proto__ (ou myArray.constructor.prototype) références Array.prototype.


Dernier arrêt dans le prototype Chaîne est Object.prototype

Puisque la propriété prototype est un objet, le dernier arrêt de la chaîne ou de la recherche de prototype est à Object.prototype. Dans le code qui suit, je crée mon tableau, qui est un tableau vide. Je tente ensuite d'accéder à une propriété de mon tableau qui n'a pas encore été défini, engageant la chaîne de recherche de prototype. le mon tableau objet est examiné pour la propriété foo. Étant absent, la propriété est recherchée à Array.prototype, mais ce n'est pas là non plus. Donc, la place finale JavaScript ressemble est Object.prototype. Comme il n’est défini dans aucun de ces trois objets, la propriété est indéfini.

Échantillon: sample123.html

 

Prenez note que la chaîne s'est arrêtée avec Object.prototype. Le dernier endroit où nous avons cherché foo était Object.prototype.

Prudent! Tout ce qui est ajouté à Object.prototype sera affiché dans une boucle in.


le prototype Chain renvoie la première propriété correspondante trouvée dans la chaîne

A l'instar de la chaîne scope, le prototype chain utilisera la première valeur trouvée lors de la recherche de chaîne.

Modification de l'exemple de code précédent, si nous ajoutions la même valeur à la Object.prototype et Array.prototype objets, puis a tenté d'accéder à une valeur sur une instance de tableau, la valeur renvoyée serait celle du Array.prototype objet.

Échantillon: sample124.html

 

Dans cet exemple, la valeur foo à Array.prototype.foo est ombrageant ou masquant la foo valeur trouvée à Object.prototype.foo. Rappelez-vous simplement que la recherche se termine lorsque la propriété est trouvée dans la chaîne, même si le même nom de propriété est également utilisé plus haut dans la chaîne..


Remplacement du prototype La propriété avec un nouvel objet supprime la propriété de constructeur par défaut

Il est possible de remplacer la valeur par défaut d’un prototype propriété avec une nouvelle valeur. Cependant, cela éliminera la propriété de constructeur par défaut trouvée dans le fichier "préconfiguré". prototype objet sauf si vous spécifiez manuellement un.

Dans le code qui suit, nous créons un Foo fonction constructeur, remplace le prototype avec un nouvel objet vide et vérifiez que la propriété du constructeur est cassée (elle fait maintenant référence à la propriété moins utile Objet prototype).

Échantillon: sample125.html

 

Si vous avez l'intention de remplacer la valeur par défaut prototype propriété (commune à certains modèles JS OOP) configurée par JavaScript, vous devez relier ensemble une propriété de constructeur faisant référence à la fonction constructeur. Dans l'exemple suivant, nous modifions notre code précédent afin que le constructeur la propriété fournira à nouveau une référence à la fonction constructeur appropriée.

Échantillon: sample126.html

 

Instances qui héritent des propriétés de prototype Obtiendra toujours les dernières valeurs

La propriété prototype est dynamique en ce sens que les instances obtiendront toujours la dernière valeur du prototype, quelle que soit la date à laquelle il a été instancié, modifié ou ajouté. Dans le code qui suit, nous créons un Foo constructeur, ajouter la propriété X au prototype, puis créez une instance de Foo () nommé FooInstance. Ensuite, nous enregistrons la valeur de X. Nous mettons ensuite à jour la valeur de x du prototype et le consignons à nouveau pour constater que notre instance a accès à la dernière valeur trouvée dans le répertoire. prototype objet.

Échantillon: sample127.html

 

Étant donné le fonctionnement de la chaîne de recherche, ce comportement ne devrait pas être surprenant. Si vous vous demandez, cela fonctionne de la même manière, que vous utilisiez ou non la valeur par défaut. prototype objet ou le remplacer avec le vôtre. Dans l'exemple suivant, je remplace la valeur par défaut prototype objet pour démontrer ce fait.

Échantillon: sample128.html

 

Remplacement du prototype La propriété avec un nouvel objet ne met pas à jour les anciennes instances

Vous pourriez penser que vous pouvez remplacer le prototype propriété entièrement à tout moment et que toutes les instances seront mises à jour, mais ce n'est pas correct. Lorsque vous créez une instance, cette instance sera liée à la prototype cela a été frappé au moment de l'instanciation. La fourniture d’un nouvel objet en tant que propriété prototype ne met pas à jour la connexion entre les instances déjà créées et le nouvel prototype.

Mais rappelez-vous, comme je l’ai indiqué précédemment, vous pouvez mettre à jour ou ajouter le prototype objet et ces valeurs restent connectées à la ou aux premières instances.

Échantillon: sample129.html

 

L'idée clé à retenir ici est qu'un prototype d'objets ne doit pas être remplacé par un nouvel objet une fois que vous avez commencé à créer des instances. Cela se traduira par des instances ayant un lien vers différents prototypes.

Les constructeurs définis par l'utilisateur peuvent exploiter la même chose prototype Héritage en tant que constructeurs natifs

J'espère qu'à ce stade de l'article, il est en train de couler dans la manière dont JavaScript lui-même exploite la prototype propriété pour héritage (Array.prototype). Ce même modèle peut être utilisé lors de la création de fonctions de constructeur non natives et définies par l'utilisateur. Dans l'exemple suivant, nous prenons le classique La personne object et imite le motif que JavaScript utilise pour l'héritage.

Échantillon: sample130.html

 

Dans ce code, un La personne() La fonction constructeur est créée. Nous ajoutons ensuite des propriétés à la prototype propriété de La personne(), qui peut être hérité par toutes les instances. Clairement, vous pouvez exploiter la chaîne de prototypes dans votre code de la même manière que JavaScript la exploite pour l'héritage d'objets natifs..

Comme bon exemple de la façon dont vous pouvez tirer parti de cela, vous pouvez créer une fonction constructeur dont les instances héritent du jambes et bras propriétés si elles ne sont pas fournies en tant que paramètres. Dans l'exemple suivant, si le La personne() Les paramètres du constructeur sont envoyés, les paramètres sont utilisés comme propriétés d'instance, mais si un ou plusieurs paramètres ne sont pas fournis, il y a un repli. Ces propriétés d’occultation masquent ou masquent les propriétés héritées, vous offrant ainsi le meilleur des deux mondes..

Échantillon: sample131.html

 

Création de chaînes d'héritage (l'intention initiale)

L'héritage prototype a été conçu pour permettre des chaînes d'héritage qui imitent les modèles d'héritage trouvés dans les langages de programmation orientés objet traditionnels. Pour qu'un objet puisse hériter d'un autre objet en JavaScript, il vous suffit d'instancier une instance de l'objet dont vous voulez hériter et de l'affecter au dossier. prototype propriété de l'objet qui hérite.

Dans l'exemple de code qui suit, Chef objets (Cody) hériter de La personne(). Cela signifie que si une propriété n'est pas trouvée dans un Chef objet, il sera ensuite recherché sur le prototype de la fonction qui a créé La personne() objets. Pour câbler l’héritage, il suffit d’instancier une instance de La personne() comme valeur pour Chef.prototype (Chef.prototype = new Person (); ).

Échantillon: sample132.html

 

Conclusion

Tout ce que nous avons fait dans cet exemple était de tirer parti d'un système déjà en place avec les objets natifs. Considérer que La personne() n'est pas contrairement à la valeur par défaut Objet() valeur pour les propriétés du prototype. En d’autres termes, c’est exactement ce qui se passe lorsqu’une propriété prototype, contenant sa valeur par défaut vide Objet() valeur, regarde le prototype de la fonction constructeur créée (Object.prototype) pour les propriétés héritées.