Si vous ne pouvez vraiment pas comprendre certaines connaissances à ce moment-là, vous pouvez le laisser partir pour le moment et le laisser à l'avenir et peut-être que vous pouvez le comprendre.
Il y a quelques mois, je tenais "JavaScript Advanced Programming (Third Edition)" et après avoir mâché l'objet, j'ai commencé à mâcher l'héritage. Cependant, après avoir mâché la chaîne prototype, je ne pouvais vraiment plus le supporter, et mon esprit est devenu de plus en plus désordonné, alors je l'ai jeté de côté et j'ai continué à regarder ce dernier. Maintenant que j'ai utilisé ces vacances d'été pour comprendre cet héritage, je trierai mes notes.
Chaînage prototype
Livrons d'abord un article. L'auteur de l'article est très bon et est équipé de photos haute définition. mdr…
Lien: [Notes d'étude] Voir la chaîne du prototype JS d'un petit point de vue
Quelques mots du texte original
Déterminez la relation entre le prototype et l'instance
Il existe deux façons de détecter la relation entre un prototype et une instance:
instanceof: détermine si l'objet est une instance d'un autre objet
Le mécanisme informatique interne de l'instance est le suivant:
functionInstance_of (l, r) {// l représente l'expression gauche, R représente l'expression droite varo = r.prototype; // prendre le prototype d'affichage de r l = l .__ proto__; // Prenez le prototype implicite de l while (true) {if (l === null) returnfalse; si (o === l) // ici le point: quand o est strictement égal à L, retournez TrueReturntrue; L = l .__ proto__; }}Le code ci-dessus est extrait de: Analyse approfondie de l'instance JavaScript de l'opérateur
isPrototypeOf (): teste si un objet existe sur la chaîne prototype d'un autre objet
Veuillez vous référer aux différences entre ces deux méthodes: JavaScript isprototype of vs instance of use
Utilisez uniquement la chaîne prototype pour obtenir l'héritage
Inconvénients: 1. Les attributs du prototype se référant à la valeur de type seront partagés par l'instance; 2. Lors de la création d'une instance d'un sous-type, les paramètres ne peuvent pas être transmis au constructeur SuperType.
functionfather () {this.name = "père"; this.friends = ['aaa', 'bbb'];} functionSon () {} Son.prototype = newfather (); fils.prototype.constructor = Son; vars1 = newson (); vars2 = newson (); console.log (s1.name); // FatherConsole.log (S2.Name); // pathers1.name = "Son"; console.log (s1.name); // sonsole.log (s2.name); // pèreConsole.log (s1.friends); // ["aaa", "bbb"] console.log (s2.friends); // ["aaa", "bbb"] s1.friends.push ('ccc', 'ddd'); console.log (s1.friends); // ["aaa", "bbb", "ccc", "ddd"] console.log (s2.friends); // ["aaa", "bb", "ccc", "ddd"]Utilisez uniquement des constructeurs pour atteindre l'héritage
Méthode d'implémentation: appelez le constructeur de supertype à l'intérieur du constructeur du sous-type (en utilisant les méthodes applicables () et call ())
Avantages: résolvez le problème de référencement des attributs de type dans le prototype, et les sous-classes peuvent transmettre des paramètres aux superclasses
Inconvénients: les instances de sous-classe ne peuvent pas accéder aux méthodes définies dans le prototype de classe parent (superclass), il n'y a donc aucun moyen de parler de la réutilisation de la fonction.
functionfather (name, amis) {this.name = name; this.friends = amis;} père.prototype.getName = function () {returnthis.name;}; functionSon (nom) {// note: pour s'assurer que le constructeur père ne remplace pas les propriétés du fils de fils. Père.call (this, name, ['aaa', 'bbb']); this.age = 22;} vars1 = newson ('Son1'); vars2 = newson ('Son2'); console.log (s1.name); // son1console.log (s2.Name); // Son2S1.Friends.push ('ccc', 'ddd'); console.log (s1.friends); // ["aaa", "bbb", "ccc", "ddd"] console.log (s2.friends); // ["aaa", "bbb"] // subclasse ne peut accéder à la méthode S1.getname () dans la classe de parents; // typeError: s1.getName n'est pas un fonctions2.getName (); // TypeError: s2.getName n'est pas une fonctionHéritage combiné
Méthode d'implémentation: utilisez la chaîne prototype pour implémenter l'héritage des propriétés et des méthodes prototypes et utilisez le constructeur pour implémenter l'hérédité des propriétés d'instance.
functionfather (name, ami) {this.name = name; this.friends = ami;} père.prototype.money = "100k $"; père.prototype.getName = function () {console.log (this.name);}; functionSon (name, Âge) {// inHériter la propriété de la classe parent Père.call (this, name, ['aaa', 'bbb']); this.age = age;} // hériter les propriétés et méthodes de la classe parent prototype Son.prototype = newfather (); Son.prototype.constructor = Son; Son.prototype.getage = function () {console.log (this.age);}; = newson ('Son1', 12); s1.friends.push ('ccc'); console.log (s1.friends); // ["aaa", "bbb", "ccc"] console.log (s1.money); // 100k $ s1.getname (); // Son1S1.Getage (); // 12vars2 = newson ('Son2', 24); console.log (s2.friends); // ["aaa", "bbb"] console.log (s2.money); // 100k $ s2.getName (); // Son2S2.Getage (); // 24L'héritage combiné évite le défaut de des chaînes ou les constructeurs prototypes unilatéralement pour mettre en œuvre l'héritage, combine leurs avantages et devient le modèle d'héritage le plus couramment utilisé en JavaScript, mais il est également défectueux, et le défaut de l'héritage combiné sera spécifiquement mentionné plus tard.
Héritage prototypique
Idée d'implémentation: utilisez des prototypes pour créer de nouveaux objets basés sur des objets existants, sans créer de types personnalisés à cause de cela.
Pour y parvenir, la fonction suivante (OBJ) est introduite
functionobj (o) {functionf () {} f.prototype = o; returnNewf ();} varPerson1 = {name: "Percy", amis: ['aaa', 'bbb']}; varPerson2 = obj (person1); person2.name = "zyj"; personne2.pouch.push ('ccc'); console.log. percyconsole.log (Person2.Name); // zyjconsole.log (Person1.friends); // ["aaa", "bbb", "ccc"] console.log (Person2.friends); // ["aaa", "bbb", "ccc"] Ecmascript 5 normalise le prototype de l'inhérence en ajoutant l'objet. Dans le cas de la transmission dans un paramètre, les méthodes object.create () et obj () se comportent de la même manière. VarPerson1 = {nom: "Percy", amis: ['aaa', 'bbb']}; varPerson2 = object.create (person1); person2.name = "zyj"; personne2.friends.push ('ccc'); console.log (personne1.name); // percyConSole.log (person2.name); // zyjconsole.log (Person1.friends); // ["aaa", "bbb", "ccc"] console.log (personne2.friends); // ["aaa", "bbb", "ccc"]Cet héritage peut être choisi lorsqu'il n'est pas nécessaire de mobiliser le constructeur pour le créer, mais je veux simplement qu'un objet reste similaire à un autre.
Héritage parasite
L'héritage parasite est une idée étroitement liée à l'héritage prototype.
Idée d'implémentation: créez une fonction qui est uniquement utilisée pour encapsuler le processus d'héritage, qui améliore en interne l'objet d'une manière ou d'une autre et renvoie enfin l'objet.
functionObj (o) {functionf () {} f.prototype = o; returnNewf ();} functionCreateSonrson (original) {// encapsule le processus d'hérédité varClone = obj (original); // créer un objet clone.showsomething = function () {// modern object console.log ("hello world!"); }; returnClone; // Return objet} varPerson = {name: "Percy"}; varPerson1 = CreateSerson (personne); console.log (personne1.name); // percyperson1.showsomething (); // Bonjour le monde!Héritage de combinaison parasite
Parlons d'abord des lacunes de notre héritage de combinaison précédente. Le plus gros problème avec l'héritage combiné est que quelle que soit la situation, le constructeur de la classe parent sera appelé deux fois: l'un est lors de la création du prototype de la sous-classe, et l'autre est lors de l'appel du constructeur de sous-classe, le constructeur de la classe parent est appelé à l'intérieur du constructeur de sous-classe.
functionfather (name, ami) {this.name = name; this.friends = ami;} père.prototype.money = "100k $"; père.prototype.getName = function () {console.log (this.name);}; functionSon (name, Âge) {// inHériter la propriété de la classe parent Père.Call (this, name, ['aaa', 'bbb']); // Le deuxième appel à père () est en fait appelé this.age = age;} // hériter les propriétés et les méthodes dans le prototype de classe parent Son.prototype = newfather (); // La première fois père () est appelée fils.prototype.constructor = Son;Le premier appel fait le prototype de la sous-classe une instance de la classe parent, de sorte que le prototype de la sous-classe obtient l'attribut d'instance de la classe parent; Le deuxième appel entraînera l'attribut d'instance de la sous-classe pour obtenir également l'attribut d'instance de la classe parent; et l'attribut d'instance de la sous-classe bloquera les attributs dupliqués avec le prototype de sous-classe par défaut. Par conséquent, après ces deux appels, des attributs inutiles apparaissent dans le prototype de sous-classe, introduisant ainsi l'héritage de la combinaison parasite pour résoudre ce problème.
L'idée derrière l'héritage de la combinaison parasite est: il n'est pas nécessaire d'appeler le constructeur de la classe parent pour spécifier le prototype de la sous-classe. Tout ce dont nous avons besoin est une copie du prototype de classe parent.
Essentiellement, il s'agit d'utiliser l'héritage parasite pour hériter du prototype de la classe parent, puis de retourner le résultat au prototype de la classe infantile.
functionObj (o) {functionf () {} f.prototype = o; returnNewf ();} functionInHeritProtype (Son, père) {varProtype = obj (père.prototype); // créer un prototype d'objet.constructor = fils; // améliorer l'objet Son.prototype = prototype; // Return Object} functionFather (name, amis) {this.name = name; this.friends = amis;} père.prototype.money = "100k $"; père.prototype.getName = function () {console.log (this.name);}; functionSon (nom, âge) {// inhériter la propriété de la classe parentale); Père.Call (ceci, nom, ['aaa', 'bbb']); this.age = age;} // hériter les propriétés et les méthodes du prototype de classe parent héritage deprototype (fils, père); Son.prototype.getage = function () {console.log (this.age);}; vars1 = newson ('son1', 12); s1.friends.push ('ccc'); console.log (s1.. ["aaa", "bbb", "ccc"] console.log (s1.money); // 100k $ s1.getName (); // Son1S1.Getage (); // 12vars2 = newson ('Son2', 24); console.log (s2.friends); // ["aaa", "bbb"] console.log (s2.money); // 100k $ s2.getName (); // Son2S2.Getage (); // 24Avantages: faire des prototypes de sous-classe éviter hériter des propriétés d'instance inutiles dans la classe parent.
Les développeurs croient généralement que l'héritage combinatoire parasite est la méthode d'héritage la plus idéale basée sur l'héritage du type.
enfin
Enfin, je recommande vivement deux articles très durs
Javascript comment fonctionne vraiment l'héritage prototypique
Diagramme de l'héritage pseudo-classique de JavaScript (besoin de traverser le mur)
Prenez une photo du deuxième article:
Après l'avoir lu, je comprends la chaîne prototype en quelques secondes. Y a-t-il quelque chose?
Ce qui précède est la collecte des informations héritées par JavaScript. Nous continuerons d'ajouter des informations pertinentes à l'avenir. Merci pour votre soutien pour ce site Web!