Question

Je définir comment deux fonctions peuvent hériter l'un de l'autre comme suit:

Function.prototype.inherit = function(parent){

function proto() {}
proto.prototype = parent.prototype;

this.prototype = new proto();
this.prototype.constructor = this;
this.prototype.parent = parent; 

}

Il me faut ensuite définir une fonction isInstance qui se comporterait comme instanceOf ou de instanceof de PHP Java. En substance, isInstance pourrait être utilisée pour déterminer si une variable est un objet instancié d'une fonction qui hérite d'une fonction de parent.

est ce que je l'ai écrit:

Function.prototype.isInstance = function(func){
if(this == func){
    return true;
} else{
    if (this.prototype.parent == undefined || this.prototype.parent == null) {
        return false;   
    } else {
        return this.prototype.parent.isInstance(func);          
    }
}

}

Ce qui fonctionne très bien lorsque l'on compare deux fonctions, mais pas lorsque l'on compare les variables instanciées.

Object2.inherit(Object1);

Object2.isInstance(Object1); //returns true

var obj2 = new Object2();

obj2.isInstance(Object1);// obj2.isInstance is not a function

Le dernier cas ci-dessus est ce que je veux travailler. Comment puis-je ajouter isInstance aux instances, pas seulement les fonctions? Et à tous les gourous javascript là-bas, ce qu'il ya des améliorations à mon code (la méthode Hériter, peut-être)?

Merci.

Était-ce utile?

La solution

  

Il me faut ensuite définir une fonction isInstance qui se comporterait comme instanceOf ou de instanceof de PHP Java.

Quel est le problème avec le propre instanceof de JavaScript?

Compte tenu de votre fonction Hériter,

function Shape() {};
function Square() {};
Square.inherit(Shape);
alert(new Square() instanceof Shape); // true

instanceof fonctionne en vérifiant si la propriété prototype du constructeur est donné dans la chaîne de prototype de l'instance. Ainsi, par exemple.

function A() {};
function B() {};
var b= new B();
A.prototype= B.prototype;
alert(b instanceof A); // true

Voilà pourquoi instanceof Shape fonctionne même si Square.prototype n'a pas été créé à l'aide new Shape; Au contraire, il a été créé par new proto(), mais étant donné que les deux proto et Shape partagent la même propriété prototype, JavaScript ne peut pas faire la différence.

Vous ne pouvez pas voir normalement la chaîne prototype (bien que Firefox et WebKit rendre disponible via la propriété __proto__), mais il est l'héritage est en fait manipulé façon à JS; la propriété Function.prototype visible est uniquement utilisée pour établir l'état initial de la chaîne de prototype à new temps.

  

Comment puis-je ajouter isInstance aux instances, pas seulement les fonctions?

Object.prototype.isInstance(c)= function() {
    return this instanceof c;
}

Je ne suis pas sûr que ce vraiment devient beaucoup si! Et dans le prototypage d'objets est souvent considéré comme de mauvais goût, car elle affecte littéralement chaque objet et peut confondre d'autres scripts à l'aide d'objets pour un mappage de recherche.

  

sont-il des améliorations à mon code (la méthode Hériter, peut-être)?

J'aime votre méthode Hériter, il est l'un des moyens plus légers et JavaScripty de faire un système d'objets.

Avec instanceof vous risquez de perdre les propriétés de parent et constructor, à moins que vous vouliez à d'autres fins de commodité. Je mettrais la parent sur la fonction constructeur bien (il est donc comme une sous-classe en connaître la classe de base), et je dirais constructor quelque chose d'autre (il est déjà propriété appelée constructor dans Firefox, mais il ne fait pas ce que vous pensez et est généralement préférable d'éviter).

Le seul inconvénient que je vois est que vous ne pouvez pas hériter de la fonction constructeur, donc chaque fois que vous faites une nouvelle sous-classe vous devez écrire un constructeur qui appelle le constructeur de base, même si le constructeur de votre sous-classe ne fait rien du tout:

function Square() {
    Shape.apply(this, arguments);
}
Square.inherit(Shape);

Autres conseils

Pourquoi avez-vous besoin de faire cela? JavaScript ne dispose pas d'une notion de hiérarchie stricte des classes pour une raison: il ne peut vraiment pas être fait. Vous pouvez probablement arriver à une solution qui fonctionne la plupart du temps, mais je ne suis pas sûr que vous pouvez couvrir tous les cas de pointe. De plus, étant donné que JavaScript n'a pas notion d'interfaces, les tests de l'héritage explicite conduit à un couplage élevé et semble violer le principes SOLIDES .

Une bien meilleure (et plus idiomatiques) façon d'aborder ce problème est d'utiliser frappe de canard . tester simplement l'existence de la méthode dont vous avez besoin, puis l'appeler. Juste être prêt à prendre une exception si nécessaire (que vous devriez faire de toute façon).

Pour quitter le bon argument de conception de côté pour un deuxième et de se concentrer sur votre problème, le problème est que vous définissez isInstance() être une méthode sur le prototype de Function. Cela signifie des objets qui sont Functions auront, tandis que les objets qui ne sont pas (comme Object1 et Object2 dans votre exemple) ne sera pas.

Je suggère que, au lieu d'essayer de le mettre en œuvre en tant que méthode, vous avez une fonction statique:

function isInstance(object, ofClass) {
  // Same logic as you have, except use 
  // object.prototype instead of this.prototype
}

Vous pouvez alors invoquer comme

isInstance(obj2, Object2);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top