Question

Je vois beaucoup de code comme celui-ci:

function Base() {}
function Sub() {}
Sub.prototype = new Base();

Cependant, si vous le faites:

s = new Sub();
print(s.constructor == Sub);

Ceci est faux. Cela me semble déroutant, puisque le constructeur de s est bien Sub. Est-ce conventionnel / préférable de faire cela?

function Base() {}
function Sub() {}
Sub.prototype = new Base();
Sub.prototype.constructor = Sub;

ou est-ce que ça n'a pas vraiment d'importance?

Était-ce utile?

La solution

"constructeur" ne fait pas ce à quoi il ressemble. Ceci, en plus de sa non-standardité, est une bonne raison d'éviter de l'utiliser - tenez-vous-en à instanceof et prototype.

Techniquement: "constructeur" n'est pas une propriété de l'instance "s", mais une propriété de l'objet prototype "Sub" qui apparaît au travers. Lorsque vous créez la fonction "Sub" dans Mozilla, vous obtenez un objet Sub.prototype par défaut nouvellement créé avec un "constructeur" renvoyant à la fonction Sub par courtoisie.

Cependant, vous remplacez ce prototype par une nouvelle base (). Le prototype par défaut d'origine avec le lien de retour vers Sub est perdu; Au lieu de cela, Sub.prototype est une instance de Base sans aucune propriété 'constructeur' de substitution. Donc:

new Sub().constructor===
Sub.prototype.constructor===
new Base().constructor===
Base.prototype.constructor===
Base

... jusqu'à l'objet le plus élémentaire dont vous n'avez pas modifié le prototype.

  

Est-ce conventionnel / préférable de le faire?

Lorsqu'il s'agit d'objets / de classes JavaScript, il n'y a pas de convention unique. Le système de métaclasses de chaque bibliothèque se comporte légèrement différemment. Je n'en ai pas vu qui écrit manuellement 'constructeur' dans chaque classe dérivée, mais cela semble être une solution aussi valable que toute autre si vous voulez vraiment avoir le constructeur réel disponible; cela rendra également le code compatible avec les navigateurs / moteurs qui ne vous donnent pas le "constructeur".

J'aimerais envisager de lui donner un nom différent, afin d'éviter toute confusion avec la propriété "constructeur" existante et au comportement différent.

Autres conseils

Si vous souhaitez vérifier si un objet est exactement une instance de Sub, utilisez l'opérateur instanceof : -

print(s instanceof Sub);

Si vous voulez savoir si un objet est une instance de Sub ou une instance d'une sous-classe de Sub, utilisez la méthode isPrototypeOf : -

print(Sub.prototype.isPrototypeOf(s));

Oui,

Sub.prototype.constructor = Sub;

vous permet d'utiliser instanceof mais il existe une meilleure solution. Regardez ici: Héritage TDS JS sur GitHub et recherchez le Modèle héritage de combinaison parasite . Le code est au format TDD. Vous devriez donc pouvoir le saisir très rapidement, puis changer les noms pour vous permettre de commencer. C’est essentiellement ce que YAHOO.lang.extend utilise (source: employé de Yahoo et auteur de JavaScript professionnel pour développeur Web de Nicholas Zakas, 2e éd., Page 181). Bon livre en passant (pas affilié en aucune façon!)

Pourquoi? Parce que le modèle classique avec lequel vous travaillez a des variables de référence staticy (si vous créez var arr = [1,2] dans l'objet de base, TOUTES les instances auront un accès en lecture / écriture et "partageront l'état" de 'arr'! Si vous utilisez le constructeur de vol, vous pouvez contourner cela. Voir mes exemples.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top