2012-08-30 7 views
10

So habe ich eine Klasse kann es für diese Klasse A. nenne ich ein paar Funktionen geschrieben, die ich so nennen kann:Wie die äußerte „diese“ Referenz in JavaScript bekommen

var a = new A(); 
a.getSomething(); 
a.putSomething(); 
a.delSomething(); 

Und so weiter . Nun dachte ich, dass ich es ein bisschen organisieren würde, damit es nicht zu unübersichtlich bekommen und wie ein bisschen mehr würde wie folgt aussehen:

a.something.get(); 
a.something.put(); 
a.something.del(); 

Und das ist, wie ich versuchte, dies zu erreichen:

A.prototype.something = { 
    get: function(){...}, 
    put: function(){...}, 
    del: function(){...} 
}; 

Aber diese Funktionen (get, put und del) müssen immer noch auf die gemeinsamen Objekte/Funktionen in A zugreifen, also brauche ich einen Verweis auf A, aber ich weiß nicht, wie dies erreicht werden kann.

Eine Option I geht so dass gefunden:

A.prototype.something = function(){ 
    var that = this; 
    return { 
    get: function(){...}, 
    ... 
    }; 
}; 

Und 'die' würde in jenen verwendet werden (get, put und del) Funktionen anstelle von 'this'. Aber das würde bedeuten, dass ich diese Funktionen so aufrufen müsste:

a.something().get(); 
... 

Das scheint mir nicht sehr nett zu sein. Gibt es eine Möglichkeit, diese Dinge so zu organisieren, wie ich es ursprünglich geplant hatte?

+0

definieren 'something' als Getter? – Eric

Antwort

4

So habe ich eine Klasse

Javascript Klassen nicht haben. Es verfügt über eine Prototypvererbung, die Klassen in begrenztem Umfang emulieren kann, aber das ist nicht nur für die Emulation von Klassen sinnvoll. Es ist viel besser, die integrierten Sprachfunktionen optimal zu nutzen, anstatt zu versuchen, JavaScript zu einer anderen Sprache zu emulieren.

So haben Sie einen Konstruktor ...

Ich habe ein paar Funktionen geschrieben, die ich so nennen kann:

var a = new A(); 
a.getSomething(); 
a.putSomething(); 
a.delSomething(); 

Vermutlich diese Methoden sind alle auf A.prototype.

Und so weiter. Nun dachte ich, ich würde organisieren es ein bisschen So wäre es nicht zu unübersichtlich bekommen und wie ein bisschen mehr würde wie folgt aussehen:

a.something.get(); 
a.something.put(); 
a.something.del(); 

Das ist nicht weniger überladen ist (für mich). Ich denke, es gibt eine gemeinsame Sache, die von etwas getan wird, und dass bekommen, setzen, etc.Methoden wollen auf ein nicht auf etwas arbeiten.

Der Wert dieser wird durch den Aufruf festgelegt, es gibt keine andere Möglichkeit, seinen Wert als mit ES5 bind festzulegen. Also muss die aufgerufene Methode irgendwie Zugriff auf a haben. Andere Antworten zeigen, wie man das mit einer Schließung macht, aber die Konsequenz ist, dass jede Instanz ihr eigenes etwas Objekt und angehängte Methoden haben muss.

Das folgende ist ähnlich, wird aber von der Schließung befreien und setzt die Methoden auf Something.prototype für ein wenig Effizienz:

function A(name) { 
    this.name = name; 
    this.something = new Something(this); 
} 


function Something(that){ 
    this.that = that; 
} 

Something.prototype.get = function() { 
    return this.that.name; 
} 
Something.prototype.put = function(prop, value) { 
    this.that[prop] = value; 
} 

var a = new A('a'); 

alert(a.something.get());  // a 
a.something.put('name', 'z'); 
alert(a.something.get());  // z 

So können Sie mehrere Somethings, die jeweils mit unterschiedlichen setzen, bekommen, etc. Methoden. Aber das intervenierende etwas Objekt ist wirklich nur ein Gerät, das mehr Speicher verwendet (wahrscheinlich eine kleine Menge) und erfordert ein extra Zeichen. Einfacher, um die etwas Methoden auf A.prototype zu halten und muss nicht den zusätzlichen Punkt (.) Eingeben.

+0

Ich bin mir bewusst, Javascripts Mangel an Klassen und was nicht, also entschuldigen Sie mich für meine Formulierung dort. Obwohl ich für dieses Prototypkonzept noch neu bin, war es für mich nicht völlig klar, dass das, was ich zu erreichen versuchte, tatsächlich unmöglich war, so wie ich es erreichen wollte. Also entschied ich, wie Sie vorgeschlagen haben, die 'something *' Methoden auf dem 'A.prototype 'zu belassen, nur für die Einfachheit und die Speicherersparnis, falls ich mehrere Instanzen von A haben werde (obwohl mit dem' Etwas. Prototyp-Methode wird dies minimal sein. Wie auch immer, danke für deine Antwort. – Deiwin

6

Sie können dies nicht zum Prototyp hinzufügen, da das Element something nicht für alle Objekte gleich ist - intern müssen seine Methoden eine Schließung für das äußere Objekt erhalten, was zum Zeitpunkt der Ausführung nicht möglich ist .

Sie müssen es im Konstruktor tun:

function A() { 
    var that = this; 
    this.something = { 
     get: function(){...}, 
     ... 
    }; 
} 
+0

Die Konsequenz ist, dass jede Instanz ihre eigenen * something * -Objekte und Instanzen von * something * -Methoden hat. – RobG

+0

@RobG: Korrekt. Ich denke, Ihr erster Punkt muss von Natur aus das Problem sein. Der zweite Punkt kann durch Verwendung einer anderen Klasse wie in Ihrer Antwort behoben werden. – Eric

0
function A() { 
    this.something = this; 
} 
A.prototype = { 
    get: function(){...}, 
    put: function(){...}, 
    del: function(){...} 
}; 

daher:

a.something.get(); 
a.something.put(); 
a.something.del(); 
+0

Was ist, wenn ich Methoden direkt zum A-Prototyp hinzufügen möchte? Was ist, wenn ich eine andere Gruppe von Methoden hinzufügen möchte, die wie folgt verwendet werden: 'a.anotherThing.get();'? – Deiwin

Verwandte Themen