Quelle est l'affectation du prototype correcte dans l'héritage javascript?

J'ai déjà lu plusieurs articles sur l'héritage js ( celui-ci , celui-ci , celui-ci , etc.)

Dans cet article de Mozilla, l'héritage "classique" est illustré comme suit: (j'ai des exemples uniformisés)

// inherit Base function Derived() { ... } Derived.prototype = new Base(); <------- Derived.prototype.constructor = Derived; <------- 

Cependant, dans cet article, je vois:

 // inherit Base function Derived() { ... } Derived.prototype = Object.create(Base.prototype); <------- Derived.prototype.constructor = Derived; 

D'ailleurs, j'ai également vu cela:

 Derived.prototype = Base.prototype; 

Et j'ai également expérimenté et je n'ai pas pu trouver l'utilisation de l'affectation du constructor :

 Derived.prototype.constructor = Derived; <--- it still work if I skip this line 

Si je saute cette ligne, new Derived() appelle correctement Derived() toute façon.

Donc, 1) ce qui est correct:

  1. Derived.prototype = new Base();
  2. Derived.prototype = Object.create(Base.prototype);
  3. Derived.prototype = Base.prototype;
  4. autre ?

Et 2) est Derived.prototype.constructor = Derived; Vraiment nécessaire? Pourquoi ?

 Derived.prototype = new Base(); 

Cela appelle le constructeur de Base juste pour configurer la chaîne de prototypes. Bien que fonctionnant parfois et donnant des résultats équivalents à Object.create , il est propice aux erreurs et devrait être évité. Lisez Quelle est la raison d'utiliser le mot-clé "nouveau" sur Derived.prototype = nouvelle Base (et pourquoi elle ne doit pas être utilisée).

 Derived.prototype = Object.create(Base.prototype); 

C'est l'état de la technique – Corriger l'héritage javascript , à dire.

 Derived.prototype = Base.prototype; 

C'est tout à fait faux . Ne pas utiliser . Cela permet aux entités Base et Derived hériter du même objet – alors qu'il (rarement) peut être utile pour avoir plusieurs constructeurs pour une "classe", ce n'est pas une "sous-classement".

Derived.prototype.constructor = Derived; Vraiment nécessaire? Pourquoi?

Cela peut être omis et votre script fonctionnera néanmoins, mais pour des raisons de commodité, vous vous attendez à ce que (new Derived).constructor === Derived . Regardez également l' héritage JavaScript et la propriété constructeur

Quelle est la manière correcte de faire l'héritage classique en JavaScript

Dans cette réponse, j'ai expliqué la différence entre 1 et 2 montrant pourquoi 2 est la meilleure façon d'imiter l'héritage classique en JavaScript.

Bref, dans la solution 1, les enfants héritent d'une instance du parent. Dans la solution 2, la classe des enfants (Derived.prototype) hérite de la classe du parent (Base.prototype). Cela impose des limitations sévères au parent, car il doit être appelé avec 0 arguments.

La troisième solution est encore pire parce que les prototypes de la classe dérivée et de la base sont le même objet, donc aucune substitution de méthode ne peut avoir lieu. Pire encore, une méthode définie dans Derived.prototype sera disponible pour toutes les instances Base et si une méthode avec le même nom avait été déclarée sur Base.prototype, elle serait simplement remplacée.

Conclusion: 2 est la véritable façon de faire l'héritage classique en JavaScript.

La configuration de la propriété constructeur est-elle nécessaire?

La définition de la propriété constructor sur le prototype la rend accessible à toutes les instances. C'est simplement pour la commodité, la partie héritage fonctionne sans elle.