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.
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.
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.
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
.
Ajouter de nouvelles méthodes et propriétés pour les variables et méthodes d'instance
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.
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.
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 :
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 :
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 :
Instance d'objet fonction
Que fait exactement le nouvel opérateur ? C’est en fait très simple, il fait trois choses.
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 ».
Ici, une nouvelle entité est créée à l'aide du constructeur Shape(), puis utilisée pour remplacer le prototype de l'objet.
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.
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 :
Regardez l'exemple de chaîne de prototype suivant :
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.
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.
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
return this.name this.age 'étudiant';
>
var box1 = new Box();
alert(box1.name);//Bill, la valeur dans le prototype
box1.name = "Lee";
Pour résumer, faisons le tri :
Copier le code
Mode usine
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