Maison  >  Article  >  interface Web  >  Quelles sont les façons d'implémenter l'héritage en javascript

Quelles sont les façons d'implémenter l'héritage en javascript

青灯夜游
青灯夜游original
2021-06-22 16:21:109574parcourir

La façon dont JavaScript implémente l'héritage : 1. L'héritage de la chaîne de prototypes ; utilise l'instance de la classe parent comme prototype de la sous-classe. 2. Héritage structurel ; utilisez le constructeur de la classe parent pour améliorer l'instance de sous-classe. 3. Héritage d'instance ; ajoutez de nouvelles fonctionnalités aux instances de classe parent et renvoyez-les en tant qu'instances de sous-classe. 4. Copiez l'héritage. 5. Héritage combiné. 6. Héritage de combinaison parasitaire.

Quelles sont les façons d'implémenter l'héritage en javascript

L'environnement d'exploitation de ce tutoriel : système Windows 7, JavaScript version 1.8.5, ordinateur Dell G3.

JS est un langage faiblement typé orienté objet, et l'héritage est également l'une de ses fonctionnalités très puissantes. Alors comment implémenter l’héritage en JS ? Attendons et voyons.

Comment implémenter l'héritage JS

Puisque nous voulons implémenter l'héritage, nous devons d'abord avoir une classe parent, le code est le suivant :

// 定义一个动物类
function Animal (name) {
  // 属性
  this.name = name || 'Animal';
  // 实例方法
  this.sleep = function(){
    console.log(this.name + '正在睡觉!');
  }
}
// 原型方法
Animal.prototype.eat = function(food) {
  console.log(this.name + '正在吃:' + food);
};

1 . Héritage de la chaîne de prototypes

Core : Utiliser l'instance de la classe parent comme prototype de la sous-classe

function Cat(){ 
}
Cat.prototype = new Animal();
Cat.prototype.name = 'cat';

// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.eat('fish'));
console.log(cat.sleep());
console.log(cat instanceof Animal); //true 
console.log(cat instanceof Cat); //true

Caractéristiques :

  • Relation d'héritage très pure, une instance est une instance d'une sous-classe et une instance de la classe parent

  • La classe parent a ajouté des méthodes prototypes/attributs prototypes, qui peuvent être accessible par les sous-classes

  • Simple et facile à mettre en œuvre

Inconvénients :

  • Pour ajouter des attributs et des méthodes aux sous-classes, vous pouvez utiliser le constructeur Cat. Dans la fonction, ajoutez des attributs d'instance à l'instance Cat. Si vous souhaitez ajouter des propriétés et des méthodes prototypes, elles doivent être exécutées après des instructions telles que new Animal().

  • L'héritage multiple ne peut pas être implémenté

  • Toutes les propriétés de l'objet prototype sont partagées par toutes les instances

  • Lors de la création d'une instance de sous-classe, les paramètres ne peuvent pas être transmis au constructeur de la classe parent

2. Héritage de construction

Core : Utiliser le constructeur de la classe parent pour améliorer l'instance de sous-classe équivaut à copier les attributs d'instance de la classe parent dans la sous-classe (aucun prototype n'est utilisé)

function Cat(name){
  Animal.call(this);
  this.name = name || 'Tom';
}

// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true

Caractéristiques :

  • Résolution du problème en 1 selon lequel les instances de sous-classe partagent les attributs de référence de la classe parent

  • Lors de la création d'une instance de sous-classe, vous pouvez transmettre des paramètres à la classe parent

  • Peut réaliser un héritage multiple (appeler plusieurs objets de classe parent)

Inconvénients :

  • Les instances ne sont pas des instances du classe parent, juste les sous-classes. Les instances de

  • ne peuvent hériter que des attributs et des méthodes d'instance de la classe parent, mais ne peuvent pas hériter des attributs/méthodes du prototype

  • ne peut pas réaliser la réutilisation des fonctions. Les sous-classes ont des copies des fonctions d'instance de classe parent, ce qui affecte les performances

3. Héritage d'instance

Core : Ajouter de nouvelles fonctionnalités. aux instances de classe parent, renvoie

function Cat(name){
  var instance = new Animal();
  instance.name = name || 'Tom';
  return instance;
}

// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // false

en tant qu'instance de sous-classe Caractéristiques :

  • ne limite pas la méthode d'appel qu'il s'agisse de new 子类() ou de 子类(), l'objet renvoyé a le même effet

Inconvénients :

  • Les instances sont des instances de la classe parent, pas des sous-classes

  • Non Prise en charge de l'héritage multiple

4. Copie de l'héritage

function Cat(name){
  var animal = new Animal();
  for(var p in animal){
    Cat.prototype[p] = animal[p];
  }
  // 如下实现修改了原型对象,会导致单个实例修改name,会影响所有实例的name值
  // Cat.prototype.name = name || 'Tom'; 错误的语句,下一句为正确的实现
  this.name = name || 'Tom';
}

// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true

Caractéristiques :

  • Prise en charge de l'héritage multiple

Inconvénients :

  • Faible efficacité et utilisation élevée de la mémoire (car les attributs de la classe parent doivent être copiés)

  • Impossible d'obtenir les méthodes non énumérables de la classe parent (les méthodes non énumérables ne sont pas accessibles en utilisant for in)

Héritage combiné5.

Noyau : En appelant le constructeur de la classe parent, héritez des attributs de la classe parent et conservez les avantages de la transmission des paramètres, puis utilisez l'instance de la classe parent comme prototype de la sous-classe pour réaliser la réutilisation des fonctions

function Cat(name){
  Animal.call(this);
  this.name = name || 'Tom';
}
Cat.prototype = new Animal();

// 组合继承也是需要修复构造函数指向的。

Cat.prototype.constructor = Cat;

// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // true

Caractéristiques :

  • compense les lacunes de la méthode 2. Vous pouvez hériter des attributs/méthodes d'instance et des attributs/méthodes de prototype

    <.>
  • est à la fois une instance d'une sous-classe et un parent. Les instances de la classe

  • n'ont pas de problème de partage d'attributs de référence

    .
  • peut transmettre des paramètres

  • les fonctions peuvent être réutilisées

Inconvénients :

  • appelle deux fois le constructeur de la classe parent et génère deux instances (l'instance de la sous-classe remplacera le prototype de la sous-classe. Celle ci-dessus est bloquée)

6. Héritage des combinaisons parasites

Noyau : Coupez les attributs d'instance de la classe parent par parasitisme. De cette façon, lorsque le constructeur de la classe parent est appelé deux fois, les méthodes/propriétés de l'instance ne seront pas initialisées deux fois, évitant ainsi les inconvénients de l'héritage combiné.

function Cat(name){
  Animal.call(this);
  this.name = name || &#39;Tom&#39;;
}
(function(){
  // 创建一个没有实例方法的类
  var Super = function(){};
  Super.prototype = Animal.prototype;
  //将实例作为子类的原型
  Cat.prototype = new Super();
})();

// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); //true
Cat.prototype.constructor = Cat; // 需要修复下构造函数

Caractéristiques :

  • Parfait

Inconvénients :

  • La mise en œuvre est plus compliqué

Code annexe :

Exemple 1 :

function Animal (name) {
  // 属性
  this.name = name || &#39;Animal&#39;;
  // 实例方法
  this.sleep = function(){
    console.log(this.name + &#39;正在睡觉!&#39;);
  }
  //实例引用属性
  this.features = [];
}
function Cat(name){
}
Cat.prototype = new Animal();

var tom = new Cat(&#39;Tom&#39;);
var kissy = new Cat(&#39;Kissy&#39;);

console.log(tom.name); // "Animal"
console.log(kissy.name); // "Animal"
console.log(tom.features); // []
console.log(kissy.features); // []

tom.name = &#39;Tom-New Name&#39;;
tom.features.push(&#39;eat&#39;);

//针对父类实例值类型成员的更改,不影响
console.log(tom.name); // "Tom-New Name"
console.log(kissy.name); // "Animal"
//针对父类实例引用类型成员的更改,会通过影响其他子类实例
console.log(tom.features); // [&#39;eat&#39;]
console.log(kissy.features); // [&#39;eat&#39;]

Analyse de la cause :

Clé point : processus de recherche d'attribut

Exécutez tom.features.push, recherchez d'abord l'attribut d'instance de l'objet tom (introuvable),

puis recherchez-le dans l'objet prototype, qui est l'exemple d'Animal. Si vous constatez que c’est le cas, insérez la valeur directement dans l’attribut caractéristiques de cet objet.

Quand console.log(kissy.features); Comme ci-dessus, s'il n'est pas disponible sur l'instance kissy, alors allez le chercher sur le prototype.

S'il existe sur le prototype, il sera renvoyé directement. Notez cependant que la valeur de l'attributfeatures dans cet objet prototype a changé.

[Recommandations associées : Tutoriel d'apprentissage Javascript]

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
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