Un. Deux prototypes
Beaucoup de gens savent que JavaScript est un héritage prototypique. Chaque constructeur a un membre prototype, à travers lequel l'héritage de JavaScript peut être magnifiquement expliqué
.
En fait, l'héritage JavaScript ne peut pas être complété en s'appuyant uniquement sur cet attribut.
Le prototype que nous utilisons dans le code pour compléter l'héritage ne sera pas abordé ici. Vous pouvez vérifier les informations
.
Un autre membre prototype invisible.
Chaque instance possède un attribut prototype pointant vers le prototype. Cet attribut n'est pas accessible, et bien sûr il ne peut pas être modifié, car c'est la base du maintien de l'héritage JavaScript.
Les objets du code ci-dessus peuvent être illustrés par le schéma suivant
2. Entretien des prototypes
L'attribut constructeur d'une instance générée par un constructeur pointe toujours vers le constructeur. Nous pensons temporairement que c'est correct.
En fait, le constructeur lui-même n'a pas l'attribut constructeur, alors d'où vient cet attribut ?
La réponse est : à partir du prototype.
Par conséquent, la conclusion suivante est tirée
Puisque nous pouvons trouver le constructeur via le constructeur, nous pouvons encore améliorer le diagramme ci-dessus.
D'après l'image ci-dessus, le résultat ci-dessus devrait être vrai, mais pourquoi est-il faux ?
Faisons une analyse maintenant.
Le prototype de GuoyansiEx a été réécrit par l'instance de Guoyansi, donc le constructeur du prototype de GuoyansiEx est naturellement issu de l'instance de Guoyansi.
Le constructeur de l'instance Guoyansi vient de Guoyansi.prototype Et Guoyansi.prototype n'a pas été réécrit,
.
Ainsi, le constructeur de Guoyansi.prototype pointe vers Guoyansi (constructeur) ;
Sur la base de l'analyse ci-dessus, les conclusions suivantes sont tirées
Si la direction du Constructeur est très précise pendant le processus de développement, vous pouvez faire ce qui suit.
3. A quoi servent les prototypes invisibles ?
Nous pouvons exploiter la chaîne prototype visible pour compléter notre héritage, mais nous ne pouvons ni voir ni exploiter cette chaîne prototype invisible.
L'héritage orienté objet a une caractéristique : la similarité. Les sous-classes ont des similitudes avec les classes parentes. Par conséquent, dans les sous-classes, vous ne pouvez pas utiliser delete pour supprimer les membres hérités des classes parentes.
Afin de conserver cette fonctionnalité, JavaScript crée un attribut prototype à l'intérieur de l'objet que nous ne pouvons pas voir et ne permet pas aux utilisateurs d'y accéder. De cette manière, les utilisateurs peuvent modifier le constructeur à n'importe quelle fin,
.
Cela ne détruira pas les caractéristiques de la classe parent que possède la sous-classe.
En bref : le prototype interne est nécessaire au mécanisme d'héritage prototypique de JavaScript, tandis que le prototype externe est nécessaire aux utilisateurs pour implémenter l'héritage
.
4. __proto__ dans le moteur Firefox SpiderMonkey
Toujours ce code.
Je souhaite maintenant accéder à l'âge des attributs du prototype de la classe parent Guoyansi en commençant par obj vers le haut.
L'idée est la suivante.
Première étape : obj2====>obj2.constructor.prototype
Partie 2 : obj2.constructor.prototype===>GuoyansiEx.prototype;
Partie 3 : GuoyansiEx.prototype===>obj1;
Partie 4 : obj1.constructor====>Guoyansi
Partie 5 : Guoyansi.prototype.age
Écrivez-le comme ceci : console.log(obj2.constructor.prototype.constructor.prototype.age)//24;
Le résultat final est 24.
Le résultat final est 24. Il peut être exécuté normalement, mais de nombreux livres disent qu'une fois le constructeur modifié, le prototype dans la classe parent est introuvable.
.
Introduit une propriété plus concise dans Firefox._proto_
SpiderMonkey ajoute par défaut un attribut nommé _proto_ à tout objet créé, qui pointe vers le prototype utilisé par le constructeur.
En fait, il s'agit de la chaîne prototype invisible dont nous avons parlé plus haut, mais elle est simplement rendue publique déguisée ici
.
Vous pouvez accéder à l'âge
comme ceci
console.log(obj2.__proto__.__proto__.age);//24
Celui-ci accède en effet avec succès à l'attribut prototype de la classe parent, mais cet attribut n'est applicable qu'à Firefox et provoquera des erreurs dans d'autres navigateurs.
Dans E5, Object.getPrototypeOf() a été étendu à Object et vous pouvez accéder aux prototypes de toutes les classes parentes.
Le résultat est : GuoyansiEx
Guoyansi
Objet
Le prototype de l'objet est nul
Personnellement, je pense que ceux-ci devraient être considérés comme l'une des essences du JavaScript orienté objet, veuillez vous y référer vous-même et l'utiliser dans vos propres projets en fonction de vos besoins