introduire
Toute programmation propose une réutilisation du code. Sinon, si vous avez besoin d'écrire un nouveau programme chaque fois que vous développez un nouveau programme ou rédigez une nouvelle fonction, ce sera un gaspillage. Cependant, la réutilisation du code est également bonne ou mauvaise. Dans les deux prochains articles, nous discuterons de la réutilisation du code. Le premier article évite l'utilisation de ces modèles autant que possible, car il apporte des problèmes dans une plus ou moins loin; La deuxième ligne est la recommandation, qui fait référence au modèle recommandé que tout le monde utilise, et il n'y aura généralement pas de problèmes.
Mode 1: Mode par défaut
Il y a souvent un problème avec la réutilisation du code du mode par défaut couramment utilisé par tout le monde. Ce mode utilise le constructeur de Parent () pour créer un objet et attribuer l'objet au prototype enfant (). Regardons le code:
La copie de code est la suivante:
Fonction héritage (c, p) {
C.prototype = new p ();
}
// Constructeur parent
fonction parent (name) {
this.name = name || 'Adam';
}
// Ajouter une fonction de dire au prototype
Parent.prototype.say = function () {
Renvoie ce.name;
};
// Le constructeur enfant est vide
fonction child (name) {
}
// Exécuter l'héritage
héritage (enfant, parent);
var kid = new child ();
console.log (kid.say ()); // "Adam"
var kiddo = new child ();
kiddo.name = "Patrick";
console.log (kiddo.say ()); // "Patrick"
// Inconvénients: vous ne pouvez pas transmettre des paramètres dans le constructeur enfant
var s = new Child ('Seth');
console.log (s.say ()); // "Adam"
L'inconvénient de ce mode est que l'enfant ne peut pas transmettre des paramètres, ce qui est fondamentalement inutile.
Modèle 2: Constructeur d'emprunt
Ce modèle est que l'enfant emprunte le constructeur du parent à appliquer, puis transmet ceci et paramètres de l'enfant à la méthode d'application:
La copie de code est la suivante:
// Constructeur parent
fonction parent (name) {
this.name = name || 'Adam';
}
// Ajouter une fonction de dire au prototype
Parent.prototype.say = function () {
Renvoie ce.name;
};
// Constructeur d'enfants
fonction child (name) {
Parent.Apply (ceci, arguments);
}
var kid = nouveau enfant ("Patrick");
console.log (kid.name); // "Patrick"
// Inconvénients: La méthode de Say n'est pas héritée du constructeur
console.log (typeof kid.say); // non défini "
L'inconvénient est également évident et la méthode Say n'est pas disponible car elle n'a pas été héritée.
Modèle 3: emprunter le constructeur et définir le prototype
Les deux modes ci-dessus ont leurs propres lacunes, alors comment supprimer les lacunes des deux? Essayons:
La copie de code est la suivante:
// Constructeur parent
fonction parent (name) {
this.name = name || 'Adam';
}
// Ajouter une fonction de dire au prototype
Parent.prototype.say = function () {
Renvoie ce.name;
};
// Constructeur d'enfants
fonction child (name) {
Parent.Apply (ceci, arguments);
}
Child.prototype = new Parent ();
var kid = nouveau enfant ("Patrick");
console.log (kid.name); // "Patrick"
console.log (typeof kid.say); // fonction
console.log (kid.say ()); // Patrick
console.dir (gamin);
supprimer kid.name;
console.log (kid.say ()); // "Adam"
Quand il fonctionne, tout est normal, mais avez-vous remarqué que le constructeur parent a été exécuté deux fois, donc bien que le programme soit disponible, il est très inefficace.
Mode 4: Prototype partagé
Le prototype partagé signifie que l'enfant et le parent utilisent le même prototype, le code est le suivant:
La copie de code est la suivante:
Fonction héritage (c, p) {
C.prototype = p.prototype;
}
// Constructeur parent
fonction parent (name) {
this.name = name || 'Adam';
}
// Ajouter une fonction de dire au prototype
Parent.prototype.say = function () {
Renvoie ce.name;
};
// Constructeur d'enfants
fonction child (name) {
}
héritage (enfant, parent);
var kid = nouveau enfant ('Patrick');
console.log (kid.name); // indéfini
console.log (typeof kid.say); // fonction
kid.name = 'patrick';
console.log (kid.say ()); // Patrick
console.dir (gamin);
Il est certain que la même chose est vraie, les paramètres de l'enfant ne sont pas reçus correctement.
Modèle 5: Constructeur temporaire
Tout d'abord, empruntez le constructeur, puis définissez le prototype enfant sur une instance du constructeur emprunté et restaurez enfin le constructeur du prototype enfant. Le code est le suivant:
La copie de code est la suivante:
/ * Fermeture * /
var inherit = (function () {
var f = fonction () {
};
fonction de retour (c, p) {
F.prototype = p.prototype;
C.prototype = new f ();
C.uber = p.prototype;
C.prototype.constructor = c;
}
} ());
fonction parent (name) {
this.name = name || 'Adam';
}
// Ajouter une fonction de dire au prototype
Parent.prototype.say = function () {
Renvoie ce.name;
};
// Constructeur d'enfants
fonction child (name) {
}
héritage (enfant, parent);
var kid = new child ();
console.log (kid.name); // indéfini
console.log (typeof kid.say); // fonction
kid.name = 'patrick';
console.log (kid.say ()); // Patrick
var kid2 = nouveau enfant ("tom");
console.log (kid.say ());
console.log (kid.constructor.name); // Enfant
console.log (kid.constructor === parent); // FAUX
Le problème est toujours le même, l'enfant ne peut pas recevoir de paramètres normalement.
Mode 6: Klass
Commençons par le code de ce modèle:
La copie de code est la suivante:
var klass = fonction (parent, accessoires) {
var enfant, f, i;
// 1.
// nouveau constructeur
Child = function () {
if (child.uber && child.uber.hasownproperty ("__ construction")) {
Child.uber .__ Construction.Apply (ceci, arguments);
}
if (child.prototype.hasownproperty ("__ construction")) {
Child.prototype .__ Construction.Apply (this, arguments);
}
};
// 2.
// Héritage
Parent = parent || Objet;
F = fonction () {
};
F.prototype = parent.prototype;
Child.prototype = new f ();
Child.uber = parent.prototype;
Child.prototype.constructor = enfant;
// 3.
// Ajouter la méthode d'implémentation
pour (i dans les accessoires) {
if (props.hasownproperty (i)) {
Child.prototype [i] = props [i];
}
}
// Renvoie la "classe"
retour de l'enfant;
};
var man = klass (null, {
__construct: fonction (quoi) {
console.log ("constructeur de l'homme");
this.name = quoi;
},
getName: function () {
Renvoie ce.name;
}
});
var d'abord = new man ('Adam'); // Logs "Constructeur de l'homme"
first.getName (); // "Adam"
var superman = klass (man, {
__construct: fonction (quoi) {
console.log ("Constructeur de Superman");
},
getName: function () {
var name = superman.uber.getname.call (this);
retourner "je suis" + nom;
}
});
var Clark = new Superman ('Clark Kent');
Clark.getName (); // "Je suis Clark Kent"
Console.log (Clark Instance Of Man); // vrai
console.log (instance Clark de Superman); // vrai
Et ça? Est-ce un peu étourdi de voir? Pour être sympa, la grammaire et la spécification de ce modèle sont les mêmes que les autres langues. Êtes-vous prêt à l'utiliser? toux. . .
Résumer
Bien que les six modes ci-dessus implémentent certaines fonctions dans certaines circonstances particulières, ils ont tous leurs propres lacunes, donc en général, tout le monde devrait éviter de les utiliser.