Chaque objet de JavaScript a un prototype de propriété intégré. L'explication de la propriété Prototype d'un objet dans JavaScript est: renvoyez une référence au prototype de type d'objet. Cela signifie que l'attribut prototype contient une référence à un autre objet JavaScript, qui agit comme parent de l'objet actuel.
La copie de code est la suivante:
A.prototype = new b ();
La compréhension du prototype ne doit pas être confondue 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 les propriétés de B. Ce qui est souligné ici, c'est le clonage plutôt que l'héritage. Cela peut se produire: le prototype de A est une instance de B, et le prototype de B est également une instance de A.
Continuez à examiner l'analyse suivante:
Variables et fonctions privées
Si les variables et fonctions définies à l'intérieur de la fonction ne sont pas fournies à l'extérieur, elles ne sont pas accessibles à l'extérieur, c'est-à-dire les variables privées et les fonctions de la fonction.
La copie de code est la suivante:
<script type = "text / javascript">
Box de fonction () {
var color = "bleu"; // variable privée
var fn = fonction () // fonction privée
{
}
}
</cript>
De cette façon, la couleur des variables et FN ne sont pas accessibles en dehors de la boîte d'objet de fonction, et elles deviennent privées:
La copie de code est la suivante:
var obj = new Box ();
alerte (obj.color); // pop-up non défini
alert (obj.fn); // identique à ci-dessus
Variables et fonctions statiques
Lorsqu'une fonction est définie, les attributs et les fonctions qui y sont ajoutés sont toujours accessibles via l'objet lui-même, mais leurs exemples ne sont pas accessibles. De telles variables et fonctions sont appelées variables statiques et fonctions statiques respectivement.
La copie de code est la suivante:
<script type = "text / javascript">
fonction obj () {};
Obj.num = 72; // variable statique
Obj.fn = fonction () // fonction statique
{
}
alerte (obj.num); // 72
alerte (typeof obj.fn) // fonction
var t = new obj ();
alerte (t.name); // non défini
alerte (typeof t.fn); // non défini
</cript>
Variables et fonctions d'instance
Dans la programmation orientée objet, en plus de certaines fonctions de bibliothèque, nous espérons toujours définir certaines propriétés et méthodes en même temps lorsque la définition d'objet, afin qu'elles puissent être accessibles après l'instanciation, et JS peut également le faire.
La copie de code est la suivante:
<script type = "text / javascript">
Box de fonction () {
this.a = []; // Variable d'instance
this.fn = function () {// méthode d'instance
}
}
console.log (typeof box.a); //indéfini
console.log (typeof box.fn); //indéfini
var box = new Box ();
console.log (typeof box.a); //objet
console.log (typeof box.fn); //fonction
</cript>
Ajouter de nouvelles méthodes et propriétés aux variables et méthodes d'instance
La copie de code est la suivante:
<script type = "text / javascript">
Box de fonction () {
this.a = []; // Variable d'instance
this.fn = function () {// méthode d'instance
}
}
var box1 = new Box ();
box1.a.push (1);
box1.fn = {};
Console.log (Box1.A); // [1]
console.log (type de box1.fn); //objet
var box2 = new Box ();
Console.log (Box2.A); // []
console.log (type de box2.fn); //fonction
</cript>
A et FN ont été modifiés dans Box1, mais pas dans Box2. Étant donné que les tableaux et les fonctions sont des objets et sont des types de référence, cela signifie que bien que les propriétés et les méthodes de Box1 soient les mêmes que celles de Box2, elles ne sont pas une référence, mais une copie des propriétés et des méthodes définies par l'objet Box.
Cela n'a aucun problème avec les propriétés, mais c'est un gros problème pour les méthodes, car les méthodes font exactement la même fonction, mais il y en a deux copies. Si un objet fonction a des milliers et des méthodes d'instance, chaque instance doit maintenir une copie de milliers de méthodes. C'est évidemment non scientifique. Que puis-je faire? Le prototype a vu le jour.
Concepts de base
Chaque fonction que nous créons a une propriété prototype, qui est un pointeur vers un objet, et son objectif est de contenir des propriétés et des méthodes qui peuvent être partagées par tous les instances d'un type spécifique. Ensuite, le prototype est l'objet Prototype de l'instance d'objet créé en appelant le constructeur.
L'avantage de l'utilisation d'un prototype est qu'il permet à une instance d'objet de partager les propriétés et les méthodes qu'il contient. Autrement dit, au lieu d'ajouter des informations de définition d'objet au constructeur, vous pouvez ajouter directement ces informations au prototype. Le principal problème avec l'utilisation des constructeurs est que chaque méthode doit être créée une fois dans chaque instance.
Dans JavaScript, il existe deux types de valeurs, de valeurs d'origine et de valeurs d'objet. Chaque objet a un prototype de propriété interne, que nous appelons généralement un prototype. La valeur du prototype peut être un objet ou un nul. Si sa valeur est un objet, l'objet doit également avoir son propre prototype. Cela forme une chaîne linéaire, que nous appelons la chaîne prototype.
signification
Les fonctions peuvent être utilisées comme constructeurs. De plus, seule la fonction a un attribut prototype et peut être accessible, mais l'instance d'objet n'a pas cet attribut, il n'y a qu'un attribut __proto__ inaccessible interne. __proto__ est un lien mystérieux dans l'objet au prototype pertinent. Selon la norme, __proto__ n'est pas divulgué au public, ce qui signifie qu'il s'agit d'une propriété privée, mais le moteur de Firefox l'a exposé et est devenu une propriété commune, à laquelle nous pouvons accéder et définir.
La copie de code est la suivante:
<script type = "text / javascript">
var Browser = function () {};
Browser.prototype.run = function () {
alerte ("Je suis gecko, un noyau de Firefox");
}
var bro = new Browser ();
Bro.run ();
</cript>
Lorsque nous appelons la méthode bro.run (), car il n'y a pas de méthode de ce type, il le recherchera dans son __proto__, c'est-à-dire Browser.prototype, de sorte que la méthode run () est finalement exécutée. (Ici, la lettre capitalisée de la fonction représente le constructeur pour distinguer les fonctions ordinaires)
Lorsque vous appelez le constructeur 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.
La copie de code est la suivante:
<script type = "text / javascript">
Fonction Person (nom) {// Fonction du constructeur
this.name = name;
}
Personne.prototype.printname = function () // objet prototype
{
alert (this.name);
}
var person1 = new personne ('byron'); // instancier l'objet
console.log (Person1 .__ proto __); // personne
console.log (personne1.constructor); // essayez-le vous-même pour voir ce que ce sera
console.log (Person.prototype); // pointer le prototype d'objet Personne
var person2 = new personne ('Frank');
</cript>
L'instance de personne Person1 contient l'attribut de nom, et il génère automatiquement un attribut __proto__, qui pointe vers le prototype de la personne, et vous pouvez accéder à la méthode de print définie dans le prototype, qui est probablement comme ceci:
Chaque fonction JavaScript a un attribut prototype, qui fait référence à un objet, qui est l'objet prototype. L'objet prototype est vide lors de l'initialisation. Nous pouvons y personnaliser toutes les propriétés et méthodes. Ces méthodes et propriétés seront héritées par les objets créés par le constructeur.
Donc, maintenant le problème est. Quelle est la relation entre le constructeur, l'instance et l'objet prototype?
La différence entre les constructeurs, les instances et les objets prototypes
Une instance est créée via un constructeur. Une fois une instance créée, il a l'attribut constructeur (pointant vers la fonction du constructeur) et l'attribut __proto__ (pointant vers l'objet prototype).
Il existe une propriété prototype dans le constructeur, qui est un pointeur vers son objet prototype.
Il existe également un pointeur (propriété du constructeur) à l'intérieur de l'objet prototype pointant vers le constructeur: personne.prototype.constructor = personne;
Les instances peuvent accéder aux propriétés et aux méthodes définies sur l'objet Prototype.
Ici, Person1 et Person2 sont des instances, et le prototype est leur prototype d'objets.
Un autre châtaignier:
La copie de code est la suivante:
<script type = "text / javascript">
Fonction Animal (nom) // accumule le constructeur
{
this.name = name; // définir les propriétés des objets
}
Animal.prototype.behavior = function () // ajouter la méthode de comportement au prototype du constructeur de classe de base
{
alert ("Ceci est un" + this.name);
}
var chien = nouvel animal ("chien"); // créer un objet chien
var chat = nouvel animal ("chat"); // créer un objet chat
Dog.behavior (); // appelle la méthode de comportement directement via l'objet chien
Cat.Behavior (); // Sortie "Ceci est un chat"
alerte (dog.behavior == Cat.Behavior); // sortie true;
</cript>
On peut voir à partir du programme exécutant des résultats que les méthodes définies sur le prototype du constructeur peuvent en effet être appelées directement via l'objet, et le code est partagé. (Vous pouvez essayer de supprimer la propriété Prototype dans animal.prototype.behavior pour voir si elle peut encore s'exécuter.) Ici, la propriété prototype pointe vers l'objet animal.
Instance d'objet Array
Regardons une instance de l'objet Array. Lorsque nous créons l'objet Array1, le modèle d'objet réel de Array1 dans le moteur JavaScript est le suivant:
La copie de code est la suivante:
var array1 = [1,2,3];
L'objet Array1 a une valeur d'attribut de longueur de 3, mais nous pouvons ajouter des éléments à Array1 par la méthode suivante:
La copie de code est la suivante:
array1.push (4);
La méthode push provient d'une méthode qui pointe vers l'objet par le membre __Proto__ de Array1 (array.prototye.push ()). C'est précisément parce que tous les objets du tableau (créés via []) contiennent un membre __proto__ pointant vers le même objet de méthode avec push, inverse, etc. (array.prototype), que ces objets de tableau peuvent utiliser Push, Inverse et d'autres méthodes.
Instance de l'objet de fonction
La copie de code est la suivante:
Base de fonction () {
this.id = "base"
}
La copie de code est la suivante:
var obj = new base ();
Quel est le résultat d'un tel code? Le modèle d'objet que nous voyons dans le moteur JavaScript est:
Qu'a fait exactement le nouvel opérateur? En fait, c'était très simple, je viens de faire trois choses.
La copie de code est la suivante:
var obj = {};
obj .__ proto__ = base.prototype;
Base.Call (obj);
Chaîne prototype
Chaîne prototype: Lorsqu'une propriété ou méthode est récupérée à partir d'un objet, si l'objet lui-même n'a pas une telle propriété ou méthode, elle recherchera l'objet prototype auquel vous associez. S'il n'y a pas de prototype, il recherchera le prédécesseur du prototype associé au prototype. S'il n'y a plus, continuez à rechercher l'objet référencé par Prototype.prototype, et ainsi de suite jusqu'à ce que le prototype ....... Le prototype n'est pas défini (le prototype de l'objet est indéfini), formant ainsi la soi-disant "chaîne prototype".
La copie de code est la suivante:
<script type = "text / javascript">
Fonction Forme () {
this.name = "forme";
this.toString = function () {
Renvoie ce.name;
}
}
fonction twoShape () {
this.name = "2 forme";
}
Triangle de fonction (côté, hauteur) {
this.name = "triangle";
this.side = côté;
this.height = hauteur;
this.getArea = function () {
Renvoie ceci.side * this.height / 2;
}
}
TwoShape.prototype = new forme ();
Triangle.prototype = new TwoShape ();
</cript>
Ici, une nouvelle entité est créée avec la forme du constructeur (), puis elle est utilisée pour écraser le prototype de l'objet.
La copie de code est la suivante:
<script type = "text / javascript">
Fonction Forme () {
this.name = "forme";
this.toString = function () {
Renvoie ce.name;
}
}
fonction twoShape () {
this.name = "2 forme";
}
Triangle de fonction (côté, hauteur) {
this.name = "triangle";
this.side = côté;
this.height = hauteur;
this.getArea = function () {
Renvoie ceci.side * this.height / 2;
}
}
TwoShape.prototype = new forme ();
Triangle.prototype = new TwoShape ();
Twoshape.prototype.constructor = twoShape;
Triangle.prototype.constructor = triangle;
var my = nouveau triangle (5,10);
My.getArea ();
my.toString (); // triangle
my.constructor; // triangle (côté, hauteur)
</cript>
Héritage prototype
Héritage du prototype: À la fin de la chaîne prototype, c'est l'objet prototype pointé par l'attribut prototype du constructeur d'objets. Cet objet prototype est l'ancêtre de tous les objets, et cet ancêtre a mis en œuvre des méthodes que tous les objets tels que ToString devraient avoir à moins. D'autres constructeurs intégrés, tels que Fonction, Boolean, String, Date et Regexp, sont hérités de cet ancêtre, mais ils définissent chacun leurs propres attributs et méthodes, de sorte que leurs descendants montrent les caractéristiques de leurs clans respectifs.
Dans ECMAScript, la méthode de mise en œuvre de l'héritage est réalisée en s'appuyant sur la chaîne prototype.
La copie de code est la suivante:
<script type = "text / javascript">
function box () {// La fonction héritée est appelée supertype (classe parent, classe de base)
this.name = "jack";
}
Fonction Tree () {// Les fonctions héréditaires sont appelées sous-types (sous-classes, classes dérivées)
this.age = 300;
}
// hériter de la chaîne prototype, affectez les attributs prototypes du sous-type
// new Box () remettra les informations dans la construction de la boîte et les informations du prototype à l'arbre
Tree.prototype = new Box (); // Tree hérite la boîte et forme une chaîne à travers le prototype.
var arbre = new arbre ();
alerte (arbre.name); // Popt Jack
</cript>
Problème avec la chaîne prototype: Bien que la chaîne prototype soit très puissante et peut être utilisée pour mettre en œuvre l'héritage, elle a également quelques problèmes. Le problème le plus important provient du prototype de valeur contenant le type de référence. Les attributs de prototypes contenant des types de référence sont partagés par toutes les instances; C'est pourquoi les attributs sont définis dans les constructeurs, pas dans les objets prototypes. Lorsque l'héritage est réalisé via un prototype, le prototype devient en fait une instance d'un autre type. Par conséquent, l'attribut d'instance d'origine devient l'attribut prototype.
Lors de la création d'une instance d'un sous-type, l'argument ne peut pas être transmis au constructeur SuperType. En fait, il convient de dire qu'il n'y a aucun moyen de transmettre des paramètres au constructeur SuperType sans affecter toutes les instances d'objet. En plus du problème qui vient de discuter en raison de l'inclusion des valeurs de type de référence dans les prototypes, il est rare d'utiliser les chaînes prototypes seules dans la pratique.
Un autre châtaignier:
La copie de code est la suivante:
<script type = "text / javascript">
Personne de fonction (nom)
{
this.name = name; // définir les propriétés des objets
};
Personne.prototype.company = "Microsoft"; // Définissez les propriétés du prototype
Personne.prototype.sayhello = fonction () // méthode de prototype
{
alert ("bonjour, je suis" + this.name + "de" + this.company);
};
var billgates = new personne ("billgates"); // créer un objet personne
Billgates.sayhello (); // hérite du contenu du prototype et des sorties "Bonjour, je suis Billgates de Microsoft"
var emplois = new personne ("emplois");
Jobs.company = "Apple"; // Définissez votre propre attribut d'entreprise pour couvrir l'attribut d'entreprise du prototype
Jobs.sayhello = function ()
{
alert ("hi" + this.name + "like" + this.company);
};
Jobs.sayhello (); // les propriétés et les méthodes que vous remplacez elles-mêmes, la sortie "Salut, les travaux comme Apple"
Billgates.sayhello (); // La couverture des emplois n'affecte pas le prototype, Billgates
</cript>
Voir l'exemple suivant de la chaîne prototype:
La copie de code est la suivante:
<script type = "text / javascript">
Fonction Year () {
this.value = 21;
}
An.prototype = {
Méthode: fonction () {
}
};
fonction hi () {
};
// Définit la propriété du prototype de HI sur l'objet d'instance de l'année
Hi.prototype = Nouvel An ();
Hi.prototype.year = 'Hello World';
Hi.prototype.constructor = hi;
var test = new Hi (); // Créer une nouvelle instance de HI
// chaîne prototype
Tester [HI Exemple]
Hi.prototype [Exemple de l'année]
{Année: 'Hello World'}
An.prototype
{méthode:…};
objet.prototype
{toString: ...};
</cript>
À partir de l'exemple ci-dessus, l'objet de test est hérité de HI.prototype et année.prototype; Par conséquent, il peut accéder à la méthode de la méthode prototype de l'année, et en même temps, il peut accéder à la valeur de la propriété d'instance
__ptoto__ Attribut
L'attribut __ptoto__ (non pris en charge par le navigateur IE) est un pointeur de l'objet prototype de l'instance. Sa fonction est de pointer vers le constructeur d'attribut prototype du constructeur. Grâce à ces deux attributs, vous pouvez accéder aux propriétés et méthodes du prototype.
Une instance d'objet dans JavaScript est essentiellement composée d'une série de propriétés. Parmi ces propriétés, il existe une propriété spéciale invisible en interne - __proto__. La valeur de cette propriété pointe vers le prototype de l'instance d'objet. Une instance d'objet n'a qu'un prototype unique.
La copie de code est la suivante:
<script type = "text / javascript">
Box de fonction () {// majuscule, représentant le constructeur
Box.prototype.name = "Trigkit4"; // Prototype Attributs
Box.prototype.age = "21";
Box.prototype.run = function () // méthode prototype
{
retourne this.name + this.age + 'études';
}
}
var box1 = new Box ();
var box2 = new Box ();
alert (box1.constructor); // construire l'attribut, vous pouvez obtenir le constructeur lui-même,
// La fonction doit être positionnée par le pointeur prototype puis obtenir le constructeur lui-même
</cript>
La différence entre l'attribut __proto__ et l'attribut prototype
Le prototype est une propriété propriétaire dans l'objet de fonction.
__proto__ est une propriété implicite d'un objet normal. Lorsqu'il est nouveau, il pointera vers l'objet indiqué par le prototype;
__ptoto__ est en fait un attribut d'un certain objet entité, tandis que le prototype est un attribut appartenant au constructeur. __ptoto__ ne peut être utilisé que dans les environnements 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 dans l'affirmative, revenez immédiatement.
2. S'il n'y a pas d'instance du constructeur, accédez à son objet Prototype et retournez immédiatement.
Objet prototype
La copie de code est la suivante:
<script type = "text / javascript">
Box de fonction () {// majuscule, représentant le constructeur
Box.prototype.name = "Trigkit4"; // Prototype Attributs
Box.prototype.age = "21";
Box.prototype.run = function () // méthode prototype
{
retourne this.name + this.age + 'études';
}
}
var box1 = new Box ();
alert (box1.name); // trigkit4, la valeur du prototype
box1.name = "Lee";
alerte (box1.name); // Lee, allez au principe
var box2 = new Box ();
alert (box2.name); // trigkit4, la valeur du prototype, non modifié par box1
</cript>
Le constructeur
La copie de code est la suivante:
<script type = "text / javascript">
Box de fonction () {
this.name = "bill";
}
Box.prototype.name = "Trigkit4"; // Prototype Attributs
Box.prototype.age = "21";
Box.prototype.run = function () // méthode prototype
{
retourne this.name + this.age + 'études';
}
var box1 = new Box ();
alert (box1.name); // facture, la valeur dans le prototype
box1.name = "Lee";
alerte (box1.name); // Lee, allez au principe
</cript>
Pour résumer, triez-le:
La copie de code est la suivante:
<script type = "text / javascript">
fonction personne () {};
Personne.prototype.name = "Trigkit4";
Personne.prototype.say = fonction () {
alerte ("hi");
}
var p1 = new personne (); // prototype est un objet prototype de p1 et p2
var p2 = new personne (); // p2 est un objet instancié, et il y a un attribut __proto__ à l'intérieur, pointant vers le prototype de la personne
console.log (p1.prototype); // non défini, cette propriété est un objet et ne peut être accessible
console.log (personne.prototype); // personne
console.log (personne.prototype.constructor); // il y a aussi un pointeur (propriété du constructeur) à l'intérieur de l'objet prototype pointant vers la fonction du constructeur
console.log (p1 .__ proto __); // cette propriété est un pointeur pointant vers l'objet prototype du prototype
p1.say (); // Les instances peuvent accéder aux propriétés et méthodes définies sur l'objet Prototype
</cript>
Modèle d'usine
La copie de code est la suivante:
fonction createObject (nom, âge) {
var obj = nouveau objet ();
obj.name = name;
obj.age = âge;
retour obj;
}
Le modèle d'usine résout le problème de la duplication à grande échelle d'objets instanciés, mais il y a un autre problème, c'est-à-dire qu'il est impossible de déterminer quelle instance de l'objet qu'ils sont.
L'utilisation de la méthode du constructeur résout non seulement le problème de l'instanciation répétée, mais résout également le problème de la reconnaissance des objets.
La différence entre l'utilisation de méthodes de constructeur et de modèles d'usine est que:
1. Créer un objet (nouvel objet ()) qui n'est pas affiché par la méthode du constructeur;
2. Attribuez directement les attributs et méthodes à cet objet
3. Aucune déclaration de retour
Lorsque le constructeur est utilisé et que le nouveau constructeur () est utilisé, un nouveau objet () est exécuté en arrière-plan;
Ceci dans le corps de fonction représente l'objet dérivé du nouvel objet ()
1. Déterminez si la propriété est dans l'instance du constructeur ou dans le prototype, vous pouvez utiliser la fonction `HasownProperty ()`
2. La façon de créer des littéraux est utilisée pour créer des attributs de constructeur ne pointera pas vers l'instance, mais vers l'objet, et la façon de créer des constructeurs est le contraire.
Pourquoi pointer vers l'objet? Parce que box.prototype = {}; cette façon d'écrire est en fait pour créer un nouvel objet.
Chaque fois qu'une fonction est créée, son prototype sera créé en même temps, et cet objet obtiendra automatiquement l'attribut de constructeur
3. S'il s'agit d'une méthode d'instance, une instanciation différente, leurs adresses de méthode sont différentes et uniques.
4. S'il s'agit d'une méthode prototype, alors leur adresse est partagée