Ich beziehe mich auf das zweite Beispiel, wo
das passiert erst beim anlegen von [Foo]-objekten ueber den
[new]-operator in verbindung mit dem durch [[Foo]] referenzierten
konstruktor.
dabei macht sich dann auch der [[SpecialIdFunctor]] mit jeder
dieser instanzen bekannt und hinterlaesst seine signatur.
gilt.
was ich vermute, aber weder recherchieren noch beweisen kann, ist,
dass hier, analog zu prototypischen erweiterungen, der kontext der
in diesem bsp. bisher einzigen oeffentliche funktoren-methode
[showSpecialId] erst zur laufzeit beim zugriff auf ebenjene methode
durch ein [Foo]-objekt aufgeloest wird.
Warum sollte das passieren (siehe unten)?
ich werf' da einfach mal ein paar begriffe in den raum:
... spaete bindung? *superspaete bindung*? ...... ich stochere da im nebel und bedarf selber der dringenden
aufklaerung ueber das echte laufzeitverhalten dieser speziellen
konstellation.
Gehen wir doch einfach mal durch, was bei dem Aufruf von new Foo(id);
(id
irgendein Wert) passiert:
new Foo(id);
Es wird ein neues Objekt angelegt (beachte FooConstructor
).
function (id) {
Diese Funktion wird aufgerufen. id hat dabei den übergebenen Wert.
SpecialIdFunctor.call(this, this);
SpecialIdFunctor
wird im Kontext von this
aufgerufen, mit dem einzigen Argument this
. Dabei passiert Folgendes:
function (that) {
that
ist nun this
aus dem Konstruktor von Foo
.
var getSpecialId=(function(){return(that.getId()+1);});
Es wird eine Funktion erzeugt und in getSpecialId gespeichert.
this.showSpecialId=(function(){return getSpecialId();});
Es wird eine Funktion erzeugt, die die zuvor erzeugte Funktion aufruft (und deren Rückgabewert zurückgibt) und als Eigenschaft von this
gespeichert.
Damit endet der Aufruf von SpecialIdFunctor
, that
und getSpecialId
bleiben erhalten (Closure) und wir kehren zum Konstruktor Foo
zurück.
this.getId=(function(){return id;});
Es wird eine Funktion erzeugt, die id
zurückgibt und als Eigenschaft von this
gespeichert.
Der Konstruktor-Aufruf endet, das erzeugte Objekt wird zurückgegeben.
Ergebnis: Drei Variablen (id
, that
, getSpecialId
), die via Closure erhalten werden, zwei Methoden in this
.
Demgegenüber:
Foo = function(id) {
var that = this;
var getSpecialId = function() {
return that.getId() + 1;
}this.getId = function() {
return id;
}this.showSpecialId = function() {
return getSpecialId();
}}
Ich mache es kurz: Drei Variablen (`id`{:.language-javascript}, `that`{:.language-javascript}, `getSpecialId`{:.language-javascript}), die via Closure erhalten werden, zwei Methoden in `this`{:.language-javascript}.
> falls ich mit meinen vermutungen richtig liege, geht die von mir
> vorgestellte variante schonender mit arbeitsspeicher um, da jede
> einzelne [[Foo]]-instanziierung weniger overhaed erzeugt, als es
> der code Deines beispiels tut. vielleicht ist mein konstrukt sogar
> schneller. klarheit schafft hier nur ein performance-test.
Dein Beispiel macht genau das Gleiche, nur komplizierter. Es müsste sogar langsamer sein, da ein zusätzlicher Funktionsaufruf nötig ist.
> > Meine ursprüngliche Frage zielte darauf ab, bestimmte Teile
> > wirklich nur einmal im Prototype zu haben, damit bestimmte
> > Funktionen (aber eben nicht alle) nur einmal vorhanden sind
> > und nicht in jeder Objektinstanz.
> wenn alles richtig gedacht war, leistet mein muster genau das.
Leider nicht.
--
Reden ist Silber, Schweigen ist Gold, meine Ausführungen sind Platin.
Self-Code: sh:( ch:? rl:( br:> n4:( ie:{ mo:) va:) de:> zu:} fl:| ss:| ls:~ js:|