Question

Je sais qu'il ya beaucoup de questions semblables sont des tonnes de grandes réponses à cette question. J'ai essayé de regarder les méthodes classiques d'héritage, ou les méthodes de fermeture, etc. D'une certaine façon, je considère qu'ils sont plus ou moins « hack » méthodes pour moi, comme il le fait pas vraiment ce que le javascript est conçu pour faire. (Bienvenue quelqu'un me corriger si je me trompe). OK, tant que cela fonctionne, je satisfais avec le motif de l'héritage classique comme:

PARENTClass = function (basevar) { do something here; };
PARENTClass.prototype = { a: b, c: d}; // prototype is auto gen 

// Inheritance goes here
CHILDClass = function (childvar) { do something; };
CHILDClass.prototype = new PARENTClass(*1); // Actual inheritance to the prototype statement
// Instance
CHILDInstance = new CHILDClass(whatever);

Ci-dessus est en quelque sorte, à ma compréhension de l'héritage de JS. Mais un scénario, je ne sais pas comment mettre en œuvre, que si je veux faire un peu lors de la création d'initialisation objet (par exemple, dans le constructeur), et peut être utilisé tout de suite le nouvel objet .... Mon illustration problème peut-être pas trop clair, alors laissez-moi utiliser ce qui suit C # Psuedo pour expliquer ce que je veux faire:

class PARENT {
    public PARENT (basevar) { ... }
}
class CHILD : PARENT {
    public CHILD (basevar) : PARENT (basevar) // constructor of child, and call parent constructor during construct.
    { ... }
}

Pour une raison quelconque (comme initialisation. Éléments de l'interface utilisateur), les mettre dans le constructeur semble être la meilleure façon de le faire. Quelqu'un at-il idée sur comment puis-je le faire.

PS: dans le * 1, je ne sais pas ce que je devrais y mettre. PS2: La situation ci-dessus, je trouve la bibliothèque AI de jquery.inherit peut faire, je me demande si ce ne bibliothèque à l'aide peut atteindre. PS3: Ou ma compréhension est erronée. Étant donné que le javascript ne vise pas à mimer POO (c'est pourquoi je l'appelle bidouille), quelle est la logique « CORRECT » mettre en œuvre.

Était-ce utile?

La solution

Il est pas bidouille en tant que tel; JavaScript est un langage prototypé, tel que défini par Wikipedia comme où:

  

.. les classes ne sont pas présents, et la réutilisation du comportement (connu sous le nom d'héritage dans les langues à base de classe) est réalisée au moyen d'un processus de clonage des objets existants qui servent de prototypes.

Comme il est dit, les classes ne sont pas utilisées en JavaScript; chaque objet que vous créez est descendu de la Object JavaScript; tous les objets JavaScript ont l'objet prototype, et toutes les instances d'objets que vous créez des méthodes et des propriétés « inherit » de l'objet prototype de leur objet. Jetez un coup d'oeil au prototype de MDC objet de référence pour plus d'informations.

De ce fait, lorsque vous appelez la ligne:

CHILDClass.prototype = new PARENTClass();

Ceci permet à l'objet CHILDClass d'ajouter des méthodes et des propriétés à l'objet prototype de l'objet PARENTClass, ce qui crée un effet similaire à l'idée de cadeau d'héritage dans les langues à base de classe. Étant donné que l'objet prototype affecte chaque instance créée de cet objet, ce qui permet les méthodes de l'objet parent et propriétés à être présentes dans tous les cas de votre objet enfant.

Si vous voulez appeler votre constructeur de la classe parent dans le constructeur de votre classe enfant, vous utilisez la fonction call JavaScript; Cela vous permet d'appeler le constructeur de la classe parent dans le contexte du constructeur de la classe des enfants, la mise en donc les propriétés nouvellement prototypées dans votre classe enfant à ce qu'ils sont définis comme dans la classe parente.

Vous n'avez pas besoin de mettre quoi que ce soit lorsque vous avez spécifié le *1, puisque cette ligne est simplement utilisée pour ajouter les méthodes et propriétés à l'objet prototype de la classe enfant; Cependant, gardez à l'esprit qu'il appelle le constructeur de la classe parente, donc s'il y a des arguments qui sont fondamentaux dans le fonctionnement du constructeur de la classe parent, vous devez vérifier que ceux-ci sont présents afin d'éviter des erreurs JavaScript.

Autres conseils

JavaScript n'a pas prise en charge intégrée des hiérarchies d'héritage comme une extension de type est censé être fait par agrégation, par exemple l'ajout de fonctionnalités souhaitée directement à l'objet lui-même ou son prototype si la propriété doit être partagée entre les instances.

Cependant, JS est assez puissant pour faire la mise en œuvre d'autres formes de construction d'objets possibles, y compris l'héritage classique.

Compte tenu fonction clone - qui est suffisant pour ajouter « true » héritage prototypique, et celui-ci ne abâtardissement de JavaScript - votre exampe peut être mis en œuvre comme ceci:

function ParentClass(baseVar) {
    // do stuff
}

// don't overwrite the prototype object if you want to keep `constructor`
// see http://joost.zeekat.nl/constructors-considered-mildly-confusing.html
ParentClass.prototype.a = 'b';
ParentClass.prototype.c = 'd';

function ChildClass(childVar) {
    // call the super constructor
    ParentClass.call(this, childVar);
}

// don't inherit from a ParentClass instance, but the actual prototype
ChildClass.prototype = clone(ParentClass.prototype);
ChildClass.prototype.e = 'f';

Il est également possible d'ajouter un peu de sucre syntaxique pour l'héritage de classes - ma propre implémentation se trouve ici .

L'exemple ci-dessus alors lu

var ParentClass = Class.extend({
    constructor: function(baseVar) {
        // do stuff
    },
    a: 'b',
    c: 'd'
});

var ChildClass = ParentClass.extend({
    e: 'f'
});

J'ai un léger javascript wrapper OOP qui fournit l'héritage « classe comme » où vous pouvez remplacer les méthodes de base ou appeler les constructeurs de base ou des membres.

Vous définissez vos classes comme ceci:

//Define the 'Cat' class
function Cat(catType, firstName, lastName)
{
    //Call the 'Animal' constructor.
    Cat.$baseNew.call(this, firstName, lastName);

    this.catType = catType;
}
//Extend Animal, and Register the 'Cat' type.
Cat.extend(Animal, { type: 'Cat' }, {
    hello: function(text)
    {
        return "meaoow: " + text;
    },
    getFullName: function()
    {
        //Call the base 'Animal' getFullName method.
        return this.catType + ": " + Cat.$base.getFullName.call(this);
    }
})

//It has a built-in type system that lets you do stuff like:

var cat = new Cat("ginger", "kitty", "kat");
Cat.getType()                     // "Cat"
cat.getBaseTypesAndSelf()         // ["Cat","Animal","Class"]
cat.getType()                     // "Cat"
cat.isTypeOf(Animal.getType())    // "True"

var dynamicCat = Class.createNew("Cat", ["tab","fat","cat"])
dynamicCat.getBaseTypesAndSelf()  // ["Cat","Animal","Class"]
dynamicCat.getFullName()          // tab: fat cat

code source disponible à: classe. js

J'ai aussi plus de détails dans mon blog sur POO en javascript

Je pensais juste que je mentionne quelques-uns des problèmes avec le schéma classique que vous allez pour:

  1. vars de référence sur la super-classe (es) seront disponibles essentiellement sur statics tous les cas. Par exemple, si vous avez var arr = [1,2,3] dans le super, et ne instance_1.arr.push (4) instance_2.arr.push (5) Tous ces cas seront "voir" les changements.
  2. Vous résolvez 1. avec la solution de Ayman qui Zakas appelle « Constructor Stealing », mais maintenant que vous appelez le constructeur deux fois: une fois pour votre prototype et une fois pour le vol du constructeur. Solution - pour votre prototype utilise une aide comme inheritPrototype (je l'ai montré la mise en œuvre tout cela dans ce post: méthode inheritPrototype FWIW, ce essentiellement provenait d'une combinaison de la page 181 du livre de Zakas et une étude Crockford.

  3. Pas de vie privée (mais là encore, vous aurez besoin d'utiliser quelque chose comme le modèle d'objet durable pour obtenir ceci et cela peut ne pas être ce que vous voulez)

  4. Définition de l'objet est laissé « ballants »: Solution - mettre une instruction if vérification pour l'une des fonctions de votre prototype, puis définir le prototype avec un prototype littéral
  5. .

J'ai des exemples en cours d'exécution de tout cela sur github !!!

Il a été tout autant d'un défi pour moi de Grok vraiment: les deux livres Zakas et Crockford sur la création d'objets et d'héritage. J'ai aussi besoin d'essayer des différents frameworks JavaScript TDD. J'ai donc décidé de créer un essai sur les deux TDD cadres et JavaScript Object Création et héritage. Il a l'exécution de code et des tests jspec! Voici le lien:* Mon GitHub Open Source Essai / Livre

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