Maison > Article > interface Web > Quelles sont les façons d'implémenter l'héritage en javascript
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.
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.
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); };
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
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
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
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)
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
<.>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 || 'Tom'; } (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 :
function Animal (name) { // 属性 this.name = name || 'Animal'; // 实例方法 this.sleep = function(){ console.log(this.name + '正在睡觉!'); } //实例引用属性 this.features = []; } function Cat(name){ } Cat.prototype = new Animal(); var tom = new Cat('Tom'); var kissy = new Cat('Kissy'); console.log(tom.name); // "Animal" console.log(kissy.name); // "Animal" console.log(tom.features); // [] console.log(kissy.features); // [] tom.name = 'Tom-New Name'; tom.features.push('eat'); //针对父类实例值类型成员的更改,不影响 console.log(tom.name); // "Tom-New Name" console.log(kissy.name); // "Animal" //针对父类实例引用类型成员的更改,会通过影响其他子类实例 console.log(tom.features); // ['eat'] console.log(kissy.features); // ['eat']Analyse de la cause :Clé point : processus de recherche d'attributExé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!