Maison > interface Web > js tutoriel > Les articles techniques d'Alibaba partagent la mise en œuvre du mécanisme d'héritage Javascript_compétences Javascript

Les articles techniques d'Alibaba partagent la mise en œuvre du mécanisme d'héritage Javascript_compétences Javascript

WBOY
Libérer: 2016-05-16 15:20:01
original
1108 Les gens l'ont consulté

En tant que langage de script, Javascript n'a pas été conçu avec des fonctionnalités orientées objet à l'esprit. Même à l'ère des navigateurs modernes et des divers frameworks/bibliothèques Javascript qui poussent comme des champignons après la pluie, il n'y a même pas de mot-clé de classe en Javascript. Si vous voulez écrire une classe, vous devez utiliser une fonction. Quant à l'héritage, à la surcharge, etc., ne vous y attendez pas.

Mais comment vivre sans héritage ? Devons-nous copier toute la logique commune pour atteindre le niveau le plus bas de réutilisation du code ?

La réponse est bien sûr - NON, nous devons donc mettre en œuvre l'héritage nous-mêmes !

Objectif

L'objectif le plus critique est bien sûr l'héritage - la sous-classe possède automatiquement toutes les propriétés et méthodes publiques de la classe parent.

Support instanceof, par exemple, c est une instance d'une sous-classe et P est une classe parent, c instanceof P doit renvoyer true.

Deuxièmement, vous devriez pouvoir remplacer (Override) les méthodes de la classe parent, et dans les méthodes de la sous-classe, vous pouvez facilement appeler la méthode du même nom de la classe parent.

Quant à la surcharge, du fait des caractéristiques du langage Javascript (aucune méthode portant le même nom ne peut être utilisée, même si leurs listes de paramètres sont différentes), elle ne peut pas être implémentée.

Conception et mise en œuvre

Les objets Javascript ont un attribut très important - __proto__, qui est le prototype. Un prototype est essentiellement un objet, il peut donc aussi avoir son propre prototype, formant ainsi une chaîne de prototypes. Lorsque vous appelez une méthode d'un objet ou lisez une propriété de l'objet, l'exécuteur Javascript fait ceci :

1. Recherchez d'abord la méthode ou l'attribut correspondant dans l'objet. S'il est introuvable,
2. Trouvez le prototype de l'objet. Si vous ne le trouvez toujours pas,
3. Trouvez
dans le prototype du prototype 4....
5. Jusqu'à ce que le prototype d'Object soit enfin trouvé, si ce n'est pas encore le cas, renvoyez undefined
Comme indiqué ci-dessous :


Cette fonctionnalité de la chaîne de prototypes est très similaire à l'héritage, donc naturellement, nous pouvons l'utiliser pour implémenter le mécanisme d'héritage. La prise en charge de la chaîne de prototypes, par exemple, en fait un bon choix.

Nous définissons la fonction extend. Cette fonction accepte deux paramètres, le premier est la classe parent et le second est la sous-classe, comme indiqué ci-dessous :

function extend(ParentClass, ChildClass) {
  ...
  return ChildClass;
}
Copier après la connexion

Cette fonction traite la sous-classe et renvoie la sous-classe. La logique de traitement est la suivante :

Établir une chaîne de prototypes

En connectant la chaîne de prototypes de la sous-classe à la chaîne de prototypes de la classe parent, la sous-classe peut automatiquement avoir les méthodes et propriétés de la classe parent :

var pp = ParentClass.prototype,
  cp = ChildClass.prototype;
function T() {};
T.prototype = pp;
ChildClass.prototype = new T();
Copier après la connexion

Afin de connecter la chaîne de prototypes, vous devez créer une instance de la classe parent et l'attribuer à la propriété prototype de la classe enfant. Mais nous ne voulons pas instancier la classe parent dans la méthode extend, nous introduisons donc une classe intermédiaire T pour résoudre ce problème.

Mettre en œuvre la réécriture

Une fois la chaîne de prototypes établie, nous devons également conserver les méthodes et les attributs du prototype de sous-classe d'origine :

Méthode

Si la classe parent a une méthode du même nom, nous utilisons une fermeture pour conserver les références à la méthode de la classe parent et à la méthode de la classe enfant. Ensuite, modifiez la référence à la méthode dans le nouveau prototype pour pointer vers une nouvelle fonction. Dans cette fonction, nous créons un attribut temporaire super, le pointons vers la méthode de la classe parent et appelons la méthode de la sous-classe, de sorte que dans la méthode de la sous-classe, la méthode de la classe parent puisse être appelée via this.super :

ChildClass.prototype[name] = (function(pm, cm) {
  return function() {
    var _super = this.super;
    this.super = pm;
    var result = cm.apply(this, arguments);
    this.super = _super;
    return result;
  };
})(pp[name], cp[name]);
Copier après la connexion

Attributs

Pour les attributs, il n'y a pas de problème d'écrasement, il suffit donc d'ajouter les attributs du prototype original de la sous-classe au nouveau prototype :

ChildClass.prototype[name] = cp[name];
Copier après la connexion

Constructeur

Afin de permettre à la sous-classe d'accéder au constructeur de la classe parent, on assigne à la classe parent le super attribut de la sous-classe :

ChildClass.super = ParentClass;
Copier après la connexion

Comment utiliser

Supposons que nous souhaitions concevoir un système de gestion qui implique les clients, les travailleurs, les managers, etc. En faisant abstraction des points communs entre les clients et les employés, nous obtenons les Personnes ; puis en faisant abstraction des points communs entre les travailleurs et les managers, nous obtenons l'Employé. De cette façon, nous obtenons la structure de classe à trois niveaux :


Le code pour implémenter cette conception est le suivant :

function People(firstname, lastname) {
  this.firstname = firstname;
  this.lastname = lastname;
}

function Employee(firstname, lastname, company) {
  Employee.super.apply(this, arguments);
  this.company = company;
}

function Manager(firstname, lastname, company, title) {
  Manager.super.apply(this, arguments);
  this.title = title;
}

Copier après la connexion

Nous voulons avoir une description pour chaque personne. Les personnes sont le nom ; les employés incluent le nom de l'entreprise après le nom et le responsable inclut le poste après la description de l'employé. Le code est le suivant :

People.prototype.summary = function() {
  return this.firstname + " " + this.lastname;
};

Employee.prototype.summary = function() {
  return this.super.call(this) + ", " + this.company;
};

Manager.prototype.summary = function() {
  return this.super.call(this) + ", " + this.title;
};

Copier après la connexion

Une fois que toutes les méthodes membres ont été définies, déclarez l'héritage de la classe (vous devez d'abord définir la méthode, puis déclarer l'héritage de la classe, sinon vous ne pouvez pas utiliser this.super dans la méthode pour appeler la méthode de la classe parent !) :

extend(People, Employee);
extend(Employee, Manager);
Copier après la connexion

Il est relativement simple d'utiliser ces classes, il suffit d'utiliser new :

var people = new People("Alice", "Dickens");
var employee = new Employee("Bob", "Ray", "Alibaba");
var manager = new Manager("Calvin", "Klein", "Alibaba", "Senior Manager");
console.log( people.summary() ); //Alice Dickens
console.log( employee.summary() ); //Bob Ray, Alibaba
console.log( manager.summary() ); //Calvin Klein, Alibaba, Senior Manager
Copier après la connexion

Cet article est bon, alors likez-le !

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal