introduire
Les quatre modes de réutilisation de code introduits dans cet article sont les meilleures pratiques et sont recommandés à tous pendant le processus de programmation.
Modèle 1: Héritage prototype
L'héritage prototype consiste à laisser l'objet parent être le prototype de l'objet enfant, afin d'atteindre l'objectif de l'héritage:
La copie de code est la suivante:
objet de fonction (o) {
fonction f () {
}
F.prototype = o;
retourner nouveau f ();
}
// Parent s'oppose à hériter
var parent = {
Nom: "Papa"
};
// nouvel objet
var child = objet (parent);
// test
console.log (child.name); // "papa"
// Constructeur parent
fonction de fonction () {
// une propriété "propre"
this.name = "Adam";
}
// ajouter de nouveaux attributs au prototype
Personne.prototype.getName = function () {
Renvoie ce.name;
};
// Créer une nouvelle personne
var papa = new personne ();
// Héritage
var kid = objet (papa);
console.log (kid.getName ()); // "Adam"
// Constructeur parent
fonction de fonction () {
// une propriété "propre"
this.name = "Adam";
}
// ajouter de nouveaux attributs au prototype
Personne.prototype.getName = function () {
Renvoie ce.name;
};
// Héritage
var kid = objet (personne.prototype);
console.log (typeof kid.getName); // "fonction", car il est défini dans le prototype
console.log (typeof kid.name); // non défini ", car seul le prototype est hérité
En même temps, ECMascript5 fournit également une méthode similaire appelée objet.Create pour hériter des objets, et l'utilisation est la suivante:
La copie de code est la suivante:
/ * Utilisez la nouvelle version d'Ecmascript 5 pour fournir des fonctionnalités * /
var child = object.create (parent);
var child = object.create (parent, {
Âge: {valeur: 2} // descripteur ECMA5
});
Console.log (Child.HasownProperty ("Age")); // vrai
De plus, les propriétés peuvent également être définies sur le deuxième paramètre d'une manière plus fine:
La copie de code est la suivante:
// Tout d'abord, définissez un nouvel objet
var man = object.create (null);
// Ensuite, créez un paramètre de configuration contenant des propriétés
// Les propriétés sont définies sur écrivative, énuable et configurable
var config = {
Écrivable: vrai,
Énumérable: vrai,
configurable: vrai
};
// utilise généralement object.defineProperty () pour ajouter de nouvelles propriétés (supports ECMascript5)
// Maintenant, pour plus de commodité, nous personnalisons une fonction d'encapsulation
var defineprop = function (obj, key, valeur) {
config.value = valeur;
Object.defineProperty (obj, key, config);
}
Defineprop (homme, «voiture», «Delorean»);
Defineprop (Man, «Dob», «1981»);
Defineprop (Man, 'Beard', false);
Ainsi, l'héritage peut être fait:
La copie de code est la suivante:
var driver = object.create (man);
DefineProp (Driver, 'Toppeed', '100MPH');
driver.topspeed // 100MPH
Mais il y a une chose à noter, c'est-à-dire que le prototype de l'objet créé par Object.Create (null) est indéfini, c'est-à-dire qu'il n'y a pas de toString et de valeur de méthodes, donc une erreur se produira lorsque l'alerte (man);, mais alerte (man.car); c'est bien.
Mode 2: Copiez tous les attributs pour l'héritage
L'héritage est de cette manière de copier toutes les propriétés de l'objet parent de l'objet enfant. Généralement, l'objet enfant peut utiliser les données de l'objet parent.
Regardons d'abord un exemple de copie superficielle:
La copie de code est la suivante:
/ * Copie superficielle * /
fonction extension (parent, enfant) {
var i;
Enfant = enfant || {};
pour (i en parent) {
if (parent.hasownproperty (i)) {
enfant [i] = parent [i];
}
}
retour de l'enfant;
}
var dad = {name: "Adam"};
var kid = extend (papa);
console.log (kid.name); // "Adam"
var papa = {
compte: [1, 2, 3],
Lit: {papier: true}
};
var kid = extend (papa);
kid.counts.push (4);
Console.log (Dad.Count.ToString ()); // "1,2,3,4"
console.log (papa.reads === kid.reads); // vrai
Sur la dernière ligne du code, vous pouvez constater que les lectures de papa et gamin sont les mêmes, c'est-à-dire qu'ils utilisent la même référence, qui est le problème causé par une copie superficielle.
Jetons un coup d'œil à la copie profonde:
La copie de code est la suivante:
/ * Copie profonde * /
fonction extenddeep (parent, enfant) {
var i,
toStr = object.prototype.tostring,
astr = "[Array d'objets]";
Enfant = enfant || {};
pour (i en parent) {
if (parent.hasownproperty (i)) {
if (typeof parent [i] === 'objet') {
enfant [i] = (tostr.call (parent [i]) === astr)? []: {};
extenddeep (parent [i], enfant [i]);
} autre {
enfant [i] = parent [i];
}
}
}
retour de l'enfant;
}
var papa = {
compte: [1, 2, 3],
Lit: {papier: true}
};
var kid = extenddeep (papa);
kid.counts.push (4);
Console.log (kid.counts.toString ()); // "1,2,3,4"
Console.log (Dad.Count.ToString ()); // "1,2,3"
console.log (papa.reads === kid.reads); // FAUX
kid.reds.paper = false;
Après une copie profonde, les deux valeurs ne sont plus égales, bingo!
Mode 3: mix-in
Mélangé est de copier une ou plusieurs (ou toutes) des propriétés (ou méthodes) d'un objet à un autre objet. Donnons un exemple:
La copie de code est la suivante:
function mix () {
var arg, prop, child = {};
pour (arg = 0; arg <arguments.length; arg + = 1) {
pour (prop dans les arguments [arg]) {
if (arguments [arg] .hasownproperty (prop)) {
enfant [prop] = arguments [arg] [prop];
}
}
}
retour de l'enfant;
}
var gâteau = mélange (
{œufs: 2, grand: true},
{beurre: 1, salé: true},
{farine: '3 tasses'},
{Sugar: "Bien sûr!" }
));
console.dir (gâteau);
La fonction de mixage copie les attributs de l'enfant de tous les paramètres passés dans l'objet enfant pour générer un nouvel objet.
Alors, comment voulons-nous simplement mélanger certains attributs? Comment faire? En fait, nous pouvons utiliser des paramètres supplémentaires pour définir les propriétés qui doivent être mélangées, telles que le mix (enfant, parent, méthode1, méthode2) afin que nous ne puissions mélanger que Method1 et Method2 dans le parent dans l'enfant. Sur le code:
La copie de code est la suivante:
// Voiture
var car = fonction (paramètres) {
this.model = settings.model || «Aucun modèle fourni»;
this.colour = settings.colour || «Aucune couleur fournie»;
};
// mixin
var mixin = function () {};
Mixin.prototype = {
DrivingForward: function () {
Console.log («Drive Forward»);
},
DriveBackward: function () {
Console.log («Drive vers l'arrière»);
}
};
// Les deux paramètres définis sont l'objet mélangé à (Recive) et l'objet mélangé en (don)
Fonction Augment (ReçuObj, GivingObj) {
// Si le nom de la méthode spécifié est fourni, il y a 3 paramètres supplémentaires
if (arguments [2]) {
pour (var i = 2, len = arguments.length; i <len; i ++) {
recevantObj.prototype [arguments [i]] = donoBj.prototype [arguments [i]];
}
}
// Si vous ne spécifiez pas le troisième paramètre ou plus de paramètres, toutes les méthodes seront mitigées
autre {
for (var méthodyname dans don dodingobj.prototype) {
// Vérifiez que l'objet de réception ne contient pas le nom à mélange, donc s'il est inclus, il ne sera pas mélangé
if (! receivingoBj.prototype [méthodyname]) {
recevantObj.prototype [méthodyname] = donoBj.prototype [méthodyname];
}
}
}
}
// Mélangez les attributs de la voiture, mais les valeurs sont mélangées avec «Drivorward» et «Drivebackward» * /
Augment (voiture, mixin, «convivialité», «drivebackward»);
// Créer une nouvelle voiture d'objet
Var Vehicle = new Car ({Model: 'Ford Escort', Couleur: 'Blue'});
// Méthode pour tester si le mélange est obtenu avec succès
véhicule.driveforward ();
véhicule.drivebackward ();
Cette méthode est plus flexible à utiliser.
Modèle 4: Méthode d'emprunt
Un objet emprunte une ou deux méthodes d'un autre objet, et il n'y a pas de connexion directe entre ces deux objets. Pas besoin d'expliquer plus, utilisez simplement le code pour expliquer:
La copie de code est la suivante:
var one = {
Nom: «Objet»,
Dites: fonction (saluer) {
return salut + ',' + this.name;
}
};
// test
console.log (one.say ('hi')); // "Salut, objet"
var deux = {
Nom: «un autre objet»
};
console.log (one.say.apply (deux, ['Hello'])); // "Bonjour, un autre objet"
// Attribuez dire à une variable, cela indiquera la variable globale
var dit = un.Say;
console.log (Say ('hoho')); // "Hoho, indéfini"
// passe un rappel de la fonction de rappel
var encoreanother = {
nom: «encore un autre objet»,
Méthode: fonction (rappel) {
return rappel ('hola');
}
};
Console.log (encoreanother.method (one.say)); // "Holla, indéfini"
fonction bind (o, m) {
return function () {
return M.Apply (o, [] .slice.call (arguments));
};
}
var twosay = bind (deux, un.say);
console.log (Twosay ('yo')); // "Yo, un autre objet"
// ecmascript 5 ajoute une méthode bind () à function.prototype afin qu'il soit facile à utiliser appliquer () et appeler ().
if (typeof function.prototype.bind === 'Undefined') {
Function.prototype.bind = fonction (thisarg) {
var fn = ceci,
Slice = array.prototype.slice,
args = Slice.Call (arguments, 1);
return function () {
return fn.apply (thisarg, args.concat (slice.call (arguments)));
};
};
}
var twosay2 = one.say.bind (deux);
Console.log (TwoSay2 ('BonJour')); // "bonjour, un autre objet"
var twosay3 = one.say.bind (deux, «Enchanté»);
console.log (twoSay3 ()); // "Enchanté, un autre objet"
Résumer
Pas besoin de résumer.