Maison  >  Article  >  interface Web  >  Introduction détaillée aux différentes méthodes d'héritage JavaScript et à leurs avantages et inconvénients

Introduction détaillée aux différentes méthodes d'héritage JavaScript et à leurs avantages et inconvénients

黄舟
黄舟original
2017-05-14 10:12:021247parcourir

Cet article présente principalement les différentes manières, avantages et inconvénients d'une compréhension approfondie de l'héritage JavaScript . Les amis intéressés peuvent s'y référer

.

Écrit devant

Cet article explique les différentes méthodes d'héritage ainsi que les avantages et les inconvénients de JavaScript.

Remarque :

est identique à "JavaScript en profondeur Création d'objets", plutôt comme des notes.

Hé, laissez-moi soupirer encore : "JavaScript Advanced Programming" est vraiment bien écrit !

1. Héritage de chaîne de prototypes

function Parent () {
  this.name = 'kevin';
}

Parent.prototype.getName = function () {
  console.log(this.name);
}

function Child () {

}

Child.prototype = new Parent();

var child1 = new Child();

console.log(child1.getName()) // kevin

Problème :

1.références attributs 🎜> est partagé par toutes les instances, par exemple :

function Parent () {
  this.names = ['kevin', 'daisy'];
}

function Child () {

}

Child.prototype = new Parent();

var child1 = new Child();

child1.names.push('yayu');

console.log(child1.names); // ["kevin", "daisy", "yayu"]

var child2 = new Child();

console.log(child2.names); // ["kevin", "daisy", "yayu"]
2. Lors de la création d'une instance de Child, les paramètres ne peuvent pas être transmis au Parent

2. > Fonction de construction (héritage classique)

function Parent () {
  this.names = ['kevin', 'daisy'];
}

function Child () {
  Parent.call(this);
}

var child1 = new Child();

child1.names.push('yayu');

console.log(child1.names); // ["kevin", "daisy", "yayu"]

var child2 = new Child();

console.log(child2.names); // ["kevin", "daisy"]
Avantages :

1. Évite que les attributs de type référence soient partagés par toutes les instances

.

2. Vous pouvez passer des paramètres à Parent in Child

Par exemple :

Inconvénients :
function Parent (name) {
  this.name = name;
}

function Child (name) {
  Parent.call(this, name);
}

var child1 = new Child('kevin');

console.log(child1.name); // kevin

var child2 = new Child('daisy');

console.log(child2.name); // daisy

Les méthodes sont définies dans le constructeur, à chaque fois qu'elles sont Les instances créées seront créées une seule fois.

3. Héritage combiné


L'héritage de chaîne prototype et l'héritage classique sont deux épées combinées.

Avantages : Combinant les avantages de l'héritage de chaîne de prototypes et des constructeurs, il s'agit du modèle d'héritage le plus couramment utilisé en JavaScript.
function Parent (name) {
  this.name = name;
  this.colors = ['red', 'blue', 'green'];
}

Parent.prototype.getName = function () {
  console.log(this.name)
}

function Child (name, age) {

  Parent.call(this, name);
  
  this.age = age;

}

Child.prototype = new Parent();

var child1 = new Child('kevin', '18');

child1.colors.push('black');

console.log(child1.name); // kevin
console.log(child1.age); // 18
console.log(child1.colors); // ["red", "blue", "green", "black"]

var child2 = new Child('daisy', '20');

console.log(child2.name); // daisy
console.log(child2.age); // 20
console.log(child2.colors); // ["red", "blue", "green"]

4. L'héritage prototypique

est l'implémentation simulée d'ES5
function createObj(o) {
  function F(){}
  F.prototype = o;
  return new F();
}
Object

.create, utilisant l'objet entrant comme prototype d'objet créé. . Inconvénients :

Les valeurs d'attribut contenant des types de référence partageront toujours la valeur correspondante, ce qui est la même que l'héritage de chaîne de prototype.

Remarque : lorsque la valeur de
var person = {
  name: 'kevin',
  friends: ['daisy', 'kelly']
}

var person1 = createObj(person);
var person2 = createObj(person);

person1.name = 'person1';
console.log(person2.name); // kevin

person1.firends.push('taylor');
console.log(person2.friends); // ["daisy", "kelly", "taylor"]
est modifiée, la valeur de

ne change pas parce que person1.name et person2.name ont des valeurs de nom indépendantes, mais à cause de. person1 , en ajoutant une valeur de nom à person2, plutôt que de modifier la valeur de nom sur le prototype. person1.name = 'person1'person1

5. Héritage parasite


Créer une fonction qui est uniquement utilisée pour encapsuler le processus d'héritage. Cette fonction améliorera l'objet sous une forme interne. l'objet est restitué.

Inconvénients : Comme le modèle de constructeur emprunté, une méthode est créée à chaque fois qu'un objet est créé.
function createObj (o) {
  var clone = object.create(o);
  clone.sayName = function () {
    console.log('hi');
  }
  return clone;
}

6. Héritage combiné parasite


Pour la commodité de la lecture de chacun, le code de l'héritage combiné est répété ici :

Le plus gros inconvénient de l'héritage combiné est que le constructeur parent est appelé deux fois.
function Parent (name) {
  this.name = name;
  this.colors = ['red', 'blue', 'green'];
}

Parent.prototype.getName = function () {
  console.log(this.name)
}

function Child (name, age) {
  Parent.call(this, name);
  this.age = age;
}

Child.prototype = new Parent();

var child1 = new Child('kevin', '18');

console.log(child1)

Une fois lors de la définition du prototype d'une instance de sous-type :

Une fois lors de la création d'une instance de sous-type :
Child.prototype = new Parent();

Rappelez l'implémentation de simulation de new , en fait , dans cette phrase, nous exécuterons :
var child1 = new Child('kevin', '18');

Ici, nous appellerons à nouveau le constructeur Parent.
Parent.call(this, name);

Donc, dans cet exemple, si nous imprimons l'objet child1, nous constaterons que Child.prototype et child1 ont tous deux un attribut appelé couleurs, et la valeur de l'attribut est ['red', 'blue', ' vert'] .

Alors, comment pouvons-nous continuer à nous améliorer et éviter les appels répétés cette fois-ci ?

Et si nous n'utilisons pas Child.prototype = new Parent(), mais laissons indirectement Child.prototype accéder à Parent.prototype ?

Voyons comment l'implémenter :

Enfin nous encapsulons cette méthode d'héritage :
function Parent (name) {
  this.name = name;
  this.colors = ['red', 'blue', 'green'];
}

Parent.prototype.getName = function () {
  console.log(this.name)
}

function Child (name, age) {
  Parent.call(this, name);
  this.age = age;
}

// 关键的三步
var F = function () {};

F.prototype = Parent.prototype;

Child.prototype = new F();


var child1 = new Child('kevin', '18');

console.log(child1);

Citant l'héritage combiné parasite dans "JavaScript Advanced Programming" Le l'éloge est :
function object(o) {
  function F() {}
  F.prototype = o;
  return new F();
}

function prototype(child, parent) {
  var prototype = object(parent.prototype);
  prototype.constructor = child;
  child.prototype = prototype;
}

// 当我们使用的时候:
prototype(Child, Parent);

La grande efficacité de cette méthode reflète le fait qu'elle n'appelle le constructeur Parent qu'une seule fois, et évite ainsi de créer des attributs inutiles et redondants sur Parent.prototype. Dans le même temps, la chaîne de prototypes reste inchangée ; par conséquent, instanceof et isPrototypeOf peuvent toujours être utilisés normalement. Les développeurs pensent généralement que l'héritage compositionnel parasite est le paradigme d'héritage le plus idéal pour les types de référence.

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