peterS.: begrenzte Sichtbarkeit lokaler Werte bzw. Objekte einer Funktion

Beitrag lesen

hallo again Olaf,

...
Ich komme mal direkt auf Dein zweites Beispiel zu sprechen
(meine Kommentare stehen hinter der entsprechenden Codezeile):
...

var Foo = (function (/id/) { // [[Foo]] constructor wrapper

...


> Dieser Code wird jedes Mal ausgeführt, wenn ich new Foo() aufrufe.  
> Richtig?  
  
nein, die von mir holprig als \*constructor wrapper\* bezeichnete  
»function expression« wird in einem rutsch initialisiert und eben  
genau einmal ausgefuehrt.  
ihr rueckgabewert auf [[Foo]] ist dann der konstruktor aller  
zukuenftigen [Foo]-objekte. im \*wrapper\* firmiert diese funktion  
noch unter [[FooConstructor]]. da nun ebendieser konstruktor im  
sichtbarkeitsbereich des wrappers angelegt wurde, kann er immer  
den im selben funktions-stack angelegten [[SpecialIdFunctor]]  
referenzieren, auch wenn letzgenannter von \*aussen\* nicht mehr  
sichtbar ist - ein klassischer »closure« - und in kurzen worten  
nochmal am pseudocode:  
  
  
~~~javascript
var Foo = (function (/*id*/) { // [[Foo]] constructor wrapper  
  
/*  
 [[Foo]] constructor wrapper ...  
*/  
 var SpecialIdFunctor = (function (that) { // [[SpecialId]] -Functor(, -Interface, -Behavior, ... -Monad?)  
/*  
 ... kapselt sowohl diesen funktor ...  
*/  
 });  
  
 var FooConstructor = (function (id) { // [[Foo]] constructor  
  
  SpecialIdFunctor.call(this, this); // applying the [Functor](, [Interface], [Behavior], ... [Monad]?)  
/*  
 ... als auch diesen konstruktor, ...  
*/  
 });  
  
 return FooConstructor;/*  
  
 ... welcher unmittelbar dannach auf [[Foo]] referenziert wird.  
*/  
})();

[[SpecialIdFunctor]] und [[FooConstructor]] *leben* in einer art
anonymen / unzugaenglichem / nicht adressierbaren universum.
[[FooConstructor]] wiederum ist nur ueber [[Foo]] zu erreichen.

bis hierhin ist also noch keinerlei instanziierung erfolgt.

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.

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.

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.

... der Rest des Codes ist mir nach und nach klar geworden.
Was ich allerdings nicht verstehe, wo jetzt die Vorteil gegenüber
dem intuitiverem folgenden Code liegen:

Foo = function(id) {

var that = this;

var getSpecialId = function() {
        return that.getId() + 1;
    }

this.getId = function() {
        return id;
    }

this.showSpecialId = function() {
        return getSpecialId();
    }

}


>   
> Sie scheint mir auf den ersten Blick innen ähnlich und nach  
> außen identisch aufgebaut, ohne Nachteile zu haben.  
  
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.  
  
ich beuge mich auch jedem urteil; wobei noch viel interessanter  
waere, wie die unterschiedlichen scripting hosts dabei abschneiden.  
  
  

> 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.  
  
  
  
so long - peterS. - pseliger@gmx.net  
  
  

-- 
»Because objects in JavaScript are so flexible, you will want to think differently about class hierarchies.  
Deep hierarchies are inappropriate. Shallow hierarchies are efficient and expressive.« - [Douglas Crockford](http://javascript.crockford.com/)  
  
[ie:( fl:) br:> va:( ls:& fo:) rl:) n3;} n4:} ss:} de:µ js:} mo:? zu:\]](http://www.peter.in-berlin.de/projekte/selfcode/?code=ie%3A%28+fl%3A%29+br%3A%3E+va%3A%28+ls%3A%26+fo%3A%29+rl%3A%29+n3%3B%7D+n4%3A%7D+ss%3A%7D+de%3A%B5+js%3A%7D+mo%3A%3F+zu%3A%5D)