Maison > interface Web > js tutoriel > Explication détaillée du prototype et de la chaîne de prototypes dans JavaScript_Basic knowledge

Explication détaillée du prototype et de la chaîne de prototypes dans JavaScript_Basic knowledge

WBOY
Libérer: 2016-05-16 16:14:32
original
1142 Les gens l'ont consulté

Chaque objet en JavaScript a un prototype d'attribut intégré. L'explication de l'attribut prototype d'un objet en Javascript est la suivante : renvoyer une référence au prototype du type d'objet. Cela signifie que l'attribut prototype contient une référence à un autre objet JavaScript qui sert d'objet parent de l'objet actuel.

Copier le code Le code est le suivant :

A.prototype = nouveau B();

Pour comprendre le prototype, il ne faut pas le confondre avec l'héritage. Le prototype de A est une instance de B. On peut comprendre que A a cloné toutes les méthodes et propriétés de B. A peut utiliser les méthodes et propriétés de B. L'accent est ici mis sur le clonage plutôt que sur l'héritage. Cette situation peut se produire : le prototype de A est une instance de B, et le prototype de B est également une instance de A.

Continuez à lire l'analyse ci-dessous :

Variables et fonctions privées

Les variables et fonctions définies à l'intérieur d'une fonction ne sont pas accessibles au monde extérieur si aucune interface n'est fournie avec le monde extérieur, c'est-à-dire que les variables et fonctions sont privées à la fonction.

Copier le code Le code est le suivant :



De cette façon, les variables color et fn ne sont pas accessibles en dehors de l'objet fonction Box, et elles deviennent privées :
Copier le code Le code est le suivant :

var obj = new Box();
alert(obj.color);//pop-up non défini
alert(obj.fn);//Identique à ci-dessus

Variables et fonctions statiques

Lorsqu'une fonction est définie et que les attributs et fonctions ajoutés par le point "." sont toujours accessibles via l'objet lui-même, mais que ses instances ne sont pas accessibles, ces variables et fonctions sont appelées respectivement variables statiques et fonctions statiques.

Copier le code Le code est le suivant :


Variables et fonctions d'instance

En programmation orientée objet, en plus de certaines fonctions de la bibliothèque, nous espérons toujours définir certaines propriétés et méthodes en même temps que l'objet est défini, qui sont accessibles après instanciation. JS peut également le faire
.

Copier le code Le code est le suivant :


Ajouter de nouvelles méthodes et propriétés pour les variables et méthodes d'instance

Copier le code Le code est le suivant :


A et fn sont modifiés dans box1, mais pas modifiés dans box2 Puisque les tableaux et les fonctions sont à la fois des objets et des types référence, cela signifie que bien que les propriétés et méthodes de box1 aient le même nom que celles de box2, elles ont le même nom. même nom. Mais ce n'est pas une référence, mais une copie des propriétés et méthodes définies par l'objet Box.

Ce n'est pas un problème pour les attributs, mais c'est un gros problème pour les méthodes, car les méthodes font exactement la même fonction, mais elles sont copiées deux fois. Si un objet fonction a des milliers et des instances de méthode, alors chaque instance de. il doit conserver une copie de milliers de méthodes, ce qui n'est évidemment pas scientifique. Que pouvons-nous faire ?

Concepts de base

Chaque fonction que nous créons a un attribut prototype, qui est un pointeur vers un objet. Le but de cet objet est de contenir des propriétés et des méthodes qui peuvent être partagées par toutes les instances d'un type spécifique. Ensuite, prototype est l'objet prototype de l'instance d'objet créée en appelant le constructeur.

L'avantage de l'utilisation de prototypes est que les instances d'objets peuvent partager les propriétés et les méthodes qu'elles contiennent. Autrement dit, au lieu d'ajouter des informations de définition sur l'objet dans le constructeur, vous pouvez ajouter ces informations directement au prototype. Le principal problème lié à l’utilisation des constructeurs est que chaque méthode doit être créée dans chaque instance.

En JavaScript, il existe deux types de valeurs, les valeurs primitives et les valeurs d'objet. Chaque objet possède un prototype de propriété interne, que nous appelons généralement le prototype. La valeur du prototype peut être un objet ou null. Si sa valeur est un objet, l'objet doit également avoir son propre prototype. Cela forme une chaîne linéaire, que nous appelons chaîne prototype.

Signification

Les fonctions peuvent être utilisées comme constructeurs. De plus, seules les fonctions ont l'attribut prototype et sont accessibles, mais les instances d'objet n'ont pas cet attribut, seulement un attribut __proto__ interne inaccessible. __proto__ est un lien cryptique dans un objet vers le prototype concerné. Selon la norme, __proto__ n'est pas ouvert au public, ce qui signifie qu'il s'agit d'une propriété privée, mais le moteur Firefox l'expose comme une propriété publique à laquelle nous pouvons accéder et définir en externe.

Copier le code Le code est le suivant :


Lorsque nous appelons la méthode Bro.run(), comme il n'existe pas de méthode de ce type dans Bro, il ira dans son __proto__ pour la trouver, qui est Browser.prototype, donc la méthode run() est finalement exécutée. (Ici, la première lettre d'une fonction en majuscule représente un constructeur pour la distinguer des fonctions ordinaires)

Lorsqu'un constructeur est appelé pour créer une instance, l'instance contiendra un pointeur interne (__proto__) pointant vers le prototype du constructeur. Cette connexion existe entre l'instance et le prototype du constructeur, pas entre l'instance et le. constructeur.

Copier le code Le code est le suivant :



L'instance de personne person1 contient l'attribut name et génère automatiquement un attribut __proto__, qui pointe vers le prototype de Person. Vous pouvez accéder à la méthode printName définie dans le prototype, qui ressemble probablement à ceci :
.

Chaque fonction JavaScript possède un attribut prototype. Cet attribut fait référence à un objet, qui est l'objet prototype. L'objet prototype est vide une fois initialisé. Nous pouvons personnaliser toutes les propriétés et méthodes qu'il contient, et ces méthodes et propriétés seront héritées par l'objet créé par le constructeur.

Alors, vient maintenant le problème. Quelle est la relation entre les constructeurs, les instances et les objets prototypes ?

La différence entre les constructeurs, les instances et les objets prototypes

Les instances sont créées via des constructeurs. Une fois qu'une instance est créée, elle possède l'attribut constructor (pointant vers le constructeur) et l'attribut __proto__ (pointant vers l'objet prototype),

Il existe un attribut prototype dans le constructeur, qui est un pointeur pointant vers son objet prototype.

Il y a aussi un pointeur (attribut constructeur) à l'intérieur de l'objet prototype pointant vers le constructeur : Person.prototype.constructor = Person;

Les instances peuvent accéder aux propriétés et méthodes définies sur l'objet prototype.

Ici person1 et person2 sont des instances, prototype est leur objet prototype.

Autre exemple :


Copier le code Le code est le suivant :


Il ressort des résultats d'exécution du programme que les méthodes définies sur le prototype du constructeur peuvent en effet être appelées directement via l'objet, et que le code est partagé. (Vous pouvez essayer de supprimer l'attribut prototype dans Animal.prototype.behaviour et voir s'il fonctionne toujours.) Ici, l'attribut prototype pointe vers l'objet Animal.

Instance d'objet tableau

Regardez un exemple d'objet tableau. Lorsque nous créons l'objet array1, le modèle objet réel de array1 dans le moteur Javascript est le suivant :

Copier le code Le code est le suivant :

var tableau1 = [1,2,3];

L'objet array1 a une valeur d'attribut length de 3, mais nous pouvons ajouter des éléments au array1 via la méthode suivante :

Copier le code Le code est le suivant :

array1.push(4);

La méthode push provient d'une méthode (Array.prototye.push()) pointée par le membre __proto__ de array1. C'est précisément parce que tous les objets tableau (créés via []) contiennent un membre __proto__ qui pointe vers le même objet (Array.prototype) avec les méthodes push, reverse et autres que ces objets tableau peuvent utiliser les méthodes push, reverse et autres.

Instance d'objet fonction

Copier le code Le code est le suivant :

fonction Base() {
This.id = "base"
}

Copier le code Le code est le suivant :

var obj = nouvelle Base();

Quel est le résultat de ce code ? Le modèle objet que nous voyons dans le moteur Javascript est :

Que fait exactement le nouvel opérateur ? C’est en fait très simple, il fait trois choses.

Copier le code Le code est le suivant :

var obj = {};
obj.__proto__ = Base.prototype
Base.call(obj);

Chaîne prototype

Chaîne de prototypes : lors de l'appel d'une propriété ou d'une méthode à partir d'un objet, si l'objet lui-même ne possède pas une telle propriété ou méthode, il ira vers son objet prototype associé pour le rechercher. Si le prototype n'en a pas, il ira à l'association du prototype. Recherchez le prototype prédécesseur, et s'il n'y en a plus, continuez à rechercher l'objet référencé par Prototype.Prototype, et ainsi de suite, jusqu'à ce que Prototype...Prototype soit indéfini (le prototype de l'objet n'est pas défini). ), formant ainsi ce qu'on appelle la « chaîne prototype ».

Copier le code Le code est le suivant :


Ici, une nouvelle entité est créée à l'aide du constructeur Shape(), puis utilisée pour remplacer le prototype de l'objet.

Copier le code Le code est le suivant :


Héritage prototype

Héritage prototypique : A la fin de la chaîne de prototypes, c'est l'objet prototype pointé par l'attribut prototype du constructeur Object. Cet objet prototype est l'ancêtre de tous les objets. Cet ancêtre implémente des méthodes telles que toString que tous les objets devraient intrinsèquement posséder. Les prototypes des autres constructeurs intégrés, tels que Function, Boolean, String, Date et RegExp, sont tous hérités de cet ancêtre, mais ils définissent chacun leurs propres propriétés et méthodes, afin que leurs descendants montrent les caractéristiques de leurs clans respectifs. Ces caractéristiques.

Dans ECMAScript, la façon d'implémenter l'héritage est de s'appuyer sur la chaîne de prototypes.

Copier le code Le code est le suivant :


Problèmes avec la chaîne de prototypes : bien que la chaîne de prototypes soit très puissante et puisse être utilisée pour implémenter l'héritage, elle présente également quelques problèmes. Le principal d’entre eux provient de prototypes de valeur contenant des types de référence. Les propriétés du prototype contenant les types référence sont partagées par toutes les instances ; c'est pourquoi les propriétés sont définies dans le constructeur plutôt que dans l'objet prototype. Lorsque l’héritage est implémenté via des prototypes, le prototype redevient en fait une instance d’un autre type. En conséquence, les propriétés de l'instance d'origine deviennent des propriétés de prototype.

Lors de la création d'une instance d'un sous-type, les paramètres ne peuvent pas être transmis au constructeur du supertype. En fait, il faut dire qu'il n'existe aucun moyen de transmettre des paramètres au constructeur d'un supertype sans affecter toutes les instances d'objet. Couplées aux problèmes qui viennent d'être évoqués en raison de l'inclusion de valeurs de type de référence dans les prototypes, les chaînes de prototypes seules sont rarement utilisées dans la pratique.

Autre exemple :

Copier le code Le code est le suivant :


Regardez l'exemple de chaîne de prototype suivant :

Copier le code Le code est le suivant :


De l'exemple ci-dessus, l'objet de test hérite de Hi.prototype et Year.prototype, il peut donc accéder à la méthode prototype de Year et il peut accéder à la valeur de l'attribut d'instance

Attribut __ptoto__

L'attribut __ptoto__ (non pris en charge par le navigateur IE) est un pointeur de l'instance vers l'objet prototype. Sa fonction est de pointer vers le constructeur d'attribut prototype du constructeur. Grâce à ces deux attributs, vous pouvez accéder aux attributs et aux méthodes. dans le prototype.

Les instances d'objet en Javascript sont essentiellement composées d'une série d'attributs. Parmi ces attributs, il existe un attribut spécial invisible interne - __proto__ La valeur de cet attribut pointe vers le prototype de l'instance d'objet, un objet n'en a qu'une. un prototype unique.

Copier le code Le code est le suivant :



La différence entre l'attribut __proto__ et l'attribut prototype

Le prototype est un attribut propriétaire dans l'objet fonction.

__proto__ est un attribut implicite des objets ordinaires lorsque new est utilisé, il pointera vers l'objet pointé par prototype

; __ptoto__ est en fait un attribut d'un objet entité, tandis que prototype est un attribut appartenant au constructeur. __ptoto__ ne peut être utilisé que dans un environnement d'apprentissage ou de débogage.

Processus d'exécution du mode prototype

1. Recherchez d'abord les attributs ou les méthodes dans l'instance du constructeur, et s'il y en a un, renvoyez-le immédiatement.

2. S'il n'y a pas d'instance du constructeur, recherchez-la dans son objet prototype. S'il y en a, revenez immédiatement

.

de l'objet prototype




Constructeur


Copier le code Le code est le suivant :



Pour résumer, faisons le tri :


Copier le code

Le code est le suivant :


Mode usine

Copier le code Le code est le suivant :

function createObject (nom, âge) {
var obj = nouvel Objet();
Obj.name = nom;
Obj.age = âge;
Retourner l'objet ;
>

Le modèle d'usine résout le problème de la duplication importante d'objets instanciés, mais il existe un autre problème, c'est-à-dire qu'il est impossible de déterminer de quel objet ils sont des instances.
L'utilisation de la méthode constructeur résout non seulement le problème de l'instanciation répétée, mais résout également le problème de l'identification des objets.

La différence entre l'utilisation de la méthode constructeur et le modèle d'usine est :

1. La méthode constructeur n'affiche pas l'objet créé (new Object());
2. Attribuez directement des propriétés et des méthodes à cet objet
3. Aucune déclaration de retour

Lorsque le constructeur est utilisé et que new constructor() est utilisé, new Object() est exécuté en arrière-plan
; Ceci dans le corps de la fonction représente l'objet produit par new Object()

1. Pour déterminer si la propriété est dans l'instance du constructeur ou dans le prototype, vous pouvez utiliser la fonction `hasOwnProperty()`
2. La façon dont les littéraux sont créés à l'aide de l'attribut constructor ne pointera pas vers l'instance, mais vers l'objet. La façon dont le constructeur est créé est l'inverse
. Pourquoi pointe vers Object ? Parce que Box.prototype = {}; cette façon d'écrire crée en fait un nouvel objet.
A chaque fois qu'une fonction est créée, son prototype sera créé en même temps, et cet objet obtiendra également automatiquement l'attribut constructeur
3. S'il s'agit d'une méthode d'instance, différentes instanciations ont des adresses de méthode différentes et sont uniques
4. S'il s'agit d'une méthode prototype, alors leurs adresses sont partagées

É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
Recommandations populaires
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal