Domanda

So che c'è un sacco di domande simili sono tonnellate di grandi risposte a questo. Ho cercato di guardare ai metodi classici di successione, o di quei metodi di chiusura ecc In qualche modo ritengo che siano più o meno "hack" metodi per me, in quanto non fa davvero quello che il javascript è stato progettato per fare. (Welcome qualcuno mi corregga se sbaglio). OK, finché funziona, soddisfo con il modello di ereditarietà classica come:

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);

Sopra è in qualche modo, alla mia comprensione l'eredità di JS. Ma uno scenario non ho idea di come implementare, è che quello che se voglio fare un po 'di inizializzazione durante la creazione dell'oggetto (cioè entro costruttore), e il nuovo oggetto può essere utilizzato subito .... Il mio illustrazione sul problema non potrebbe essere troppo chiaro, così mi ha lasciato usare il seguente C # Psuedo di spiegare quello che voglio fare:

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

Per qualche motivo (come init. Elementi dell'interfaccia utente), mettendoli nel costruttore sembra il modo migliore per farlo. Qualcuno ha idea su come posso farlo.

PS: nel * 1, non ho idea di che cosa devo mettere lì. PS2: La situazione di cui sopra ho fatto trovato la biblioteca jquery.inherit può fare, mi chiedo se non usando la libreria può raggiungerlo. PS3: O la mia comprensione è sbagliato. Dal momento che javascript non è destinato a mimare OOP (è per questo che lo chiamo hack), qual è la logica "corretto" per implementare questo.

È stato utile?

Soluzione

Non è un mod in quanto tale; JavaScript è un linguaggio prototipato, come definito da Wikipedia come dove:

  

.. classi non sono presenti, e il riutilizzo comportamento (noto come ereditarietà in linguaggi basati) viene eseguita mediante un processo di clonazione oggetti esistenti che servono come prototipi.

Come si dice, le classi non sono utilizzati in JavaScript; ogni oggetto che si crea è disceso dal Object JavaScript; tutti gli oggetti JavaScript abbiano l'oggetto prototype, e tutte le istanze di oggetti creati metodi 'inherit' e oggetti di prototipo oggetto del loro oggetto. Date un'occhiata al MDC prototipo oggetto di riferimento per ulteriori informazioni.

A partire da questo, quando si chiama la linea:

CHILDClass.prototype = new PARENTClass();

In questo modo l'oggetto CHILDClass di aggiungere metodi e proprietà per il suo oggetto prototipo dall'oggetto PARENTClass, che crea un effetto simile al concetto di ereditarietà presenti nei linguaggi basati su classi. Poiché l'oggetto prototype colpisce ogni istanza creata di quell'oggetto, questo permette metodi e le proprietà dell'oggetto principale di essere presenti in ogni istante del vostro oggetto secondario.

Se si desidera chiamare costruttore del classe genitore nel costruttore del classe figlia, si utilizza la funzione call JavaScript; questo consente di chiamare il costruttore della classe genitore nel contesto della costruzione della classe bambino, impostando quindi le proprietà di nuova creazione del prototipo della tua classe bambino per quello che sono impostati come nella classe padre.

È inoltre non c'è bisogno di mettere nulla in cui è stato specificato il *1, dal momento che la linea è semplicemente utilizzato per aggiungere i metodi e proprietà per il prototipo oggetto della classe minore; tuttavia, tenere a mente che chiama il costruttore della classe genitore, quindi se ci sono argomenti che sono fondamentali per il funzionamento del costruttore della classe genitore, si dovrebbe verificare che questi siano presenti in modo da evitare errori JavaScript.

Altri suggerimenti

È possibile richiamare manualmente il costruttore genitore nel costruttore della sottoclasse in questo modo:

CHILDClass = function (basevar) {
  PARENTClass.call(this, basevar);
  // do something;
};

Il trucco sta usando il metodo call, che consente di richiamare un metodo nel contesto di un oggetto diverso. Vedere la documentazione di call per ulteriori dettagli.

JavaScript non ha il supporto integrato per gerarchie di ereditarietà come tipo di estensione dovrebbe essere fatto tramite l'aggregazione, cioè l'aggiunta di funzionalità desiderata direttamente all'oggetto stesso o il suo prototipo se la proprietà deve essere condiviso tra le istanze.

Tuttavia, JS è abbastanza potente per fare attuare altre forme di costruzione oggetti possibili, tra cui l'eredità classica.

Dato un clone funzione - che è sufficiente aggiungere 'vero' eredità prototipo, e non imbastardimento di JavaScript artificiali - la vostra exampe può essere implementato in questo modo:

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';

E 'anche possibile aggiungere un po' di zucchero sintattico per l'ereditarietà di classe a base - la mia propria implementazione può essere trovato qui .

L'esempio dall'alto sarebbe quindi leggere

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

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

Ho un javascript OOP wrapper che fornisce 'Classe-like' eredità in cui è possibile sostituire i metodi di base o chiamare i costruttori di base o membri leggero.

È possibile definire le vostre classi in questo modo:

//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

il codice sorgente disponibile all'indirizzo: Class. js

Ho anche maggiori dettagli nel mio blog post su OOP in javascript

Ho pensato di citare alcuni dei problemi con il modello classico si sta andando per:

    Vars
  1. di riferimento sulla super classe (es) saranno disponibili come essenzialmente statica su tutte le istanze. Ad esempio, se si dispone di var arr = [1,2,3] nel super, e DO instance_1.arr.push (4) instance_2.arr.push (5) tutti questi casi sarà "vedere" le modifiche.
  2. Così si risolve 1. con la soluzione di Ayman, che Zakas chiama "Costruttore Rubare", ma ora si chiama il costruttore due volte: una volta per il vostro prototipo e una volta per il furto di costruzione. Soluzione - per il vostro prototipo utilizza un aiutante come inheritPrototype (ho mostrato tutta attuazione del presente in questo post: inheritPrototype metodo FWIW, questo in sostanza è venuto da una combinazione di pagina 181 del libro di Zakas e qualche studio Crockford.

  3. Nessuna privacy (ma poi di nuovo, avresti bisogno di usare qualcosa come il modello oggetto durevole per ottenere questo e che non può essere quello che vuoi)

  4. definizione oggetto viene lasciato "penzoloni": Soluzione - ha messo un'istruzione if verifica per una qualsiasi delle funzioni del vostro prototipo e poi definire il prototipo con un prototipo letterale
  5. .

Ho esecuzione esempi di tutto questo su GitHub !!!

E 'stato tanto di una sfida per me di Grok veramente sia: Zakas e Crockford libri sulla creazione di oggetti ed eredità. Ho anche bisogno di provare alcuni diversi contesti JavaScript TDD. Così ho deciso di creare un saggio su entrambi TDD quadri e JavaScript Object Creation & eredità. E 'l'esecuzione di codice e test jspec! Ecco il link: * mio saggio GitHub Open Source / Libro

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top