Maison > interface Web > js tutoriel > Explication détaillée de la maintenance de la chaîne de prototypes Javascript et des compétences en matière d'héritage_javascript

Explication détaillée de la maintenance de la chaîne de prototypes Javascript et des compétences en matière d'héritage_javascript

WBOY
Libérer: 2016-05-16 16:30:27
original
1459 Les gens l'ont consulté

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.

Copier le code Le code est le suivant :

//Déclaration du constructeur
fonction Guoyansi(){ }
Fonction GuoyansiEx(){}
//Héritage prototype
​​​​​ GuoyansiEx.prototype=new Guoyansi();
//Créer un objet
      var g1=new GuoyansiEx();
      var g2=new GuoyansiEx();

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.

Copier le code Le code est le suivant :

fonction Guoyansi(){ }
var obj1=nouveau Guoyansi();
console.log(obj1.constructor===Guoyansi);//true

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

Copier le code Le code est le suivant :
obj1.constructor===Guoyansi.prototype.constructor= ==Guoyansi

Puisque nous pouvons trouver le constructeur via le constructeur, nous pouvons encore améliorer le diagramme ci-dessus.

Copier le code Le code est le suivant :

fonction GuoyansiEx(){}
                                GuoyansiEx.prototype=new Guoyansi();
console.log(GuoyansiEx.constructor===GuoyansiEx)//false

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

Copier le code Le code est le suivant :
GuoyansiEx.constructor===Guoyansi.constructor=== Guoyansi;

Si la direction du Constructeur est très précise pendant le processus de développement, vous pouvez faire ce qui suit.

Copier le code Le code est le suivant :

/**Méthode 1 :**/
fonction Guoyansi(){}
fonction GuoyansiEx(){}
                                GuoyansiEx.prototype=new Guoyansi();
                                                                                                                      GuoyansiEx.prototype.constructor=GuoyansiEx;//Réinitialiser le pointeur du constructeur.

Copier le code Le code est le suivant :

/**
Méthode 2
            **/
fonction Guoyansi(){}
fonction GuoyansiEx(){
This.constructor=arguments.callee;
            }
​​​​​​ GuoyansiEx.prototype=new Guoyansi();

Copier le code Le code est le suivant :

/**
Méthode 3
            **/
fonction Guoyansi(){}
fonction GuoyansiEx(){
This.constructor=GuoyansiEx;
            }
​​​​​​ GuoyansiEx.prototype=new Guoyansi();

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.

Copier le code Le code est le suivant :

fonction Guoyansi(){}
                 Guoyansi.prototype.age=24;
fonction GuoyansiEx(){}
            var obj1=new Guoyansi();
                           GuoyansiEx.prototype=obj1;
​​​​​​ GuoyansiEx.prototype.constructor=GuoyansiEx;//Réinitialiser le pointeur du constructeur.
            var obj2=new GuoyansiEx();

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.

Copier le code Le code est le suivant :

fonction Guoyansi(){}
                 Guoyansi.prototype.age=24;
fonction GuoyansiEx(){}
            var obj1=new Guoyansi();
                           GuoyansiEx.prototype=obj1;
​​​​​​ GuoyansiEx.prototype.constructor=GuoyansiEx;//Réinitialiser le pointeur du constructeur.
            var obj2=new GuoyansiEx();
          var proto=Object.getPrototypeOf(obj2);
             while(proto){
console.log(proto.constructor);
                   proto=Object.getPrototypeOf(proto);
            }
console.log(proto "objet prototype");

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

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal