Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 15 von 16
  1. #1
    Avatar von Albu
    Albu ist offline Foren-Gott
    registriert
    04-07-2001
    Beiträge
    13.501

    Einführung OOP in Javascript (und Actionscript)

    Array ist genauso wie Object, Date, Math, Screen oder String (usw.) eine Klasse in JS. Das ganze DOM ist aus Objekten/Klassen zusammengebaut. Vermutlich sind alle Klassen in JS von Object abgeleitet, so daß Object die Mutter allen Übels ist Dadurch erben alle abgeleiteten (Kinder-) Klassen/Objekte die Eigenschaften und Funktionen von Object.
    Der Vorteil bei JS gegenüber C++ ist, das man jederzeit jede beliebige Funktion eines Objektes oder der ganze Klasse verändern, hinzufügen oder löschen kann. Bei C++ ist dies z.B. zur Laufzeit nicht möglich.
    Der Unterschied zwischen Objekt und Klasse in JS ist, wie in anderen OOP Sprachen, daß Objekte Instanzen einer Klasse sind. Array, Object, Date, Math, Screen usw. sind zunächst einmal alles Klassen. Allerdings sind z.B. Math und Screen automatisch verfügbar, d.h. sie werden vom Browser automatisch unter dem Namen Math oder Screen instanziert, oder die Funktionen sind statisch definiert, d.h. man benötigt keine Instanz zum Aufrufen der Funktionen (was der wahrscheinlichere Fall sein wird).
    Instanzen werden entweder direkt (über new) oder indirekt (z.B. alle Objekte des DOMs eines konkreten HTML Dokuments oder ["1", "2", ...]) angelegt.
    Wenn man eine Instanz einer Klasse angelegt hat, dann kann man alle Funktionen und Eigenschaften benutzen, ohne daß andere Instanzen / Objekte davon beeinflußt werden.
    Zwei der wichtigsten Klassen zur Abbildung von Daten und Datenstrukturen sind dabei Object und Array. Die Funktion von Array erschließt sich dem (angehenden) Programmierer fast sofort, Object (hab ich in Selfhtml noch nicht gefunden) hat irgendwie weder Funktionen, noch Eigenschaften, ist eigentlich eine leere Klasse, deren Instanzen keine Funktion haben können. Falsch!
    Da ich jederzeit neue Eigenschaften und Funktionen zu jedem Objekt und zu jeder Klasse definieren kann, kann ich auch das Objekt einer sinnvollen Aufgabe zuführen.
    Ein neues Object lege ich ganz einfach so an:
    myCoords = new Object ();
    Da myOb noch leer ist, kann ich zunächst nichts damit anfangen. Wenn ich es aber mit Leben fülle, dann wird es plötzlich ein sinnvolles Objekt:
    myCoords.x = 100;
    myCoords.y = 200;
    Jetzt habe ich ein Objekt, welches die beiden Variablen x und y enthält. Wenn ich jetzt also Funktionen zur Bearbeitung von Koordinaten benutze/schreibe, dann kann ich nun statt zwei Parametern ein Objekt mit den zwei Werten übergeben, die Parameterzahl verringert sich (natürlich muß die Empfänger-Funktion entsprechend angepaßt werden).
    Der Zugriff auf die Eigenschaften erfolgt dann ganz normal:
    myCoords.x oder myCoords ["x"]
    Wie man sehen kann kann auch der Zugriff über den Array Operator ([]) erfolgen. Dies erlaubt es die Klasse Object als Hash zu mißbrauchen. Ein Hash ist im Grunde ein Array, welches nicht fortlaufend durchnummeriert ist, sondern als Schlüssel eben Texte oder Strings verwendet. Dies eignet sich z.B. dafür, wenn man auf Daten zugreifen möchte, die nicht über eine eindeutige Zahl referneziert werden können, bzw. wo dies nicht sinnvoll ist. Wenn ich also fünf Einträge aus der DB habe, die mit den IDs 5, 7, 100, 560 und 10020 versehen sind, dann wäre es dumm daraus ein Array zu machen und die ID als Index zu benutzen, denn dann würde ein Array enstehen, welches 10021 Einträge hätte.
    Bei einem Hash habe ich nur 5 Einträge, und da ein Hash i.d.R. auch mit entsprechenden internen Datenstrukturen wie Binärbäume (oder ähnliches) arbeitet, ist der Zugriff trotz Strings ziemlichschnell.
    Ein Object kann man, wie auch die Arrays, indirekt instanzieren:
    myCoords = {x: 100, y:200};
    oder auch direkt beim Aufruf einer Funktion:
    calcCoords ({x: 100, y:200});

    Für Arrays gilt nahezu das gleiche, außer das ein Array schon fertige Funktionen mitbringt, die den Umgang mit einem Array erleichtern.
    Lediglich die indirekte Instanzierung ist anders, damit JS unterscheiden kann, ob ein Object oder ein Array erzeugt werden soll:
    myArr = [1, 2, 3];

    myArr = new Array (1, 2, 3);

    myArr = new Array ();
    myArr.push (1);myArr.push (2);myArr.push (3);
    das Ergebnis ist identisch.

    Soweit so gut. Es steht natürlich jedem offen diese beiden Datenstrukturen zusammen mit konventionellen Variablentypen zu kombinieren und zu verschachteln.
    also z.B.
    myMatrix = [{x: 1, y: 0, z: 0}, {x: 0, y: 1, z: 0}, {x: 0, y: 0, z: 1}]
    so kann jede erdenkliche Datenstruktur erzeugt werden.

    Jetzt nochmal zurück zur Aussage, daß man Funktionen und Eigenschaften jederzeit an bestehende Objekte und Klassen anhängen kann. Das man einfach einem leeren Objekt vom Typ Object neue Eigenschaften (x, y) anhängen kann, konnte man oben sehen. Neue Funktionen sind auch kein Problem:
    myCoords.setCoords = function (x,y) { this.x = x; this.y = y; }

    Will ich gleich allen Objekten einer Klasse eine neue Funktion spendieren, dann kann ich natürlich jedesmal beim Instanzieren diese Funktion hinzufügen, was darin resultiert, daß ich aufpassen muß, keine zu vergessen und einem Haufen Speicherplatz, der durch n Kopien der gleichen Funktion in jeder einzelnen Instanz verschwendet wird. Besser wäre es hier die Funktion gleich der ganzen Klasse zur Verfügung zu stellen. Auch dies geht:
    Object.prototype.setCoords = function (x,y) { this.x = x; this.y = y; }
    Schon haben alle Instanzen von Object die Funktion setCoords. Ob sie nun wollen oder nicht. Da aber alle anderen Objekte von Object abgeleitet sind, heißt das, daß auch alle Arrays, Strings, usw. diese Funktion jetzt besitzen. Was natürlich nicht unbedingt so gut ist, da ja nur Koordinaten Objekte diese Funktion besitzen sollten. Und da man nach Möglichkeit sehr vorsichtig sein sollte mit dem Hinzufügen von neuen Funktionen an bestehende Klassen, um möglichst wenig Nebenwirkungen zu verursachen und man also den minimalst möglichen Einschnitt machen sollte, ist es selten eine gute Idee an Object selbst ranzutreten.
    Wenn man aber Funktionen zur Array Bearbeitung basteln möchte, dann sollte man sie so allgemein halten, damit man sie problemlos an die Array Klasse anhängen kann.
    Vorsichtig muß man sein, wenn man Standard-Funktionen umschreibt. Ich könnte ja z.B. die sort Funktion des Arrays umschreiben, um dort meine eigene Sortierung zu programmieren. Allerdings ist diese dann in JS und nicht in Assembler geschrieben, was für einen Geschwindigkeitsnachteil sorgt. Außerdem betrifft es eben alle Arrays und das könnte negative Auswirkungen auf andere intere Array Objekte haben, die man gar nicht vorheresagen kann. Solche Funktionen sollte man also nur überschreiben, wenn man genau weiß, was man tut, bzw. sollte sie nur in einer einzelnen Instanz überschreiben, denn dann wirkt sie nur dort, alle anderen Arrays benutzen die eingebaute sort Funktion.

    Um wieder zum Koordinaten Objekt zurückzukommen, wenn man hier eigene Funktionen definieren will, dann ist es sinnvoll eine ganz eigene Klasse zu definieren. Dies geht in JS folgendermaßen:
    CCoordinates = function (x, y)
    {
    // constructor
    this.init ();
    this.setCoords (x, y);
    }

    // erbt von Object [optional]
    CCoordinates.prototype = new Object ();

    CCoordinates.prototype.init = function ()
    {
    // initialize
    x = 0; y = 0;
    }

    CCoordinates.prototype.setCoords = function (x, y)
    { this.x = x; this.y = y; }

    myCoords = new CCoordinates (100, 200);
    alert (myCoords.x + ";" + myCoords.y);


    So das waren eine Menge Infos, ich habe alles soweit auf Lauffähigkeit (im Opera ) getestet, das Gesagte gilt 1:1 auch für Actionscript, d.h. kann man es genauso gut auch in Flash verwenden (mit Ausnahme des "alert"s ).
    1. Get people to play Space Taxi
    2. Sell real estates on neptun
    3. Profit!

    IE is not a browser, it is a scream.


    Outside of a dog, a book is man's best friend. Inside of a dog, it's too dark to read.

  2. #2
    Avatar von MOTH
    MOTH ist offline Haudegen
    registriert
    10-03-2002
    Ort
    Haan / DDorf
    Beiträge
    643
    wow ich bin beeindruckt . ist es überhaupt möglich, JavaScript mit hilfe von bibliotheken win32-lauffähig zu machen? Dass man quasi wie in C++ sowas wie

    #include <Win32Definitionen.h>

    einfügt, um z.b. fenster darzustellen, und am ende compiliert?

  3. #3
    Avatar von Albu
    Albu ist offline Foren-Gott
    registriert
    04-07-2001
    Beiträge
    13.501
    Originally posted by MOTH
    wow ich bin beeindruckt . ist es überhaupt möglich, JavaScript mit hilfe von bibliotheken win32-lauffähig zu machen? Dass man quasi wie in C++ sowas wie

    #include <Win32Definitionen.h>

    einfügt, um z.b. fenster darzustellen, und am ende compiliert?
    Also JS ist eine interpretierte Sprache und soweit ich weiß gibt es keinen Compiler für JS. Wenn Du Dir AS anguckst, dann wirst Du feststellen, daß es dort schon eine #include Anweisung gibt. C Header Dateien wirst Du aber nicht einbinden können, die Sprache auf Source Code Ebene zu mischen unterstützt weder C noch JS / AS. Außerdem welchen Sinn hätte es eine Win32 Umgebung für JS zu schaffen? Die ganze Plattformunabhängigkeit hinüber, schnarchlangsam im Vergleich zu einer vernünftigen Sprache (selbst VB ist schneller [manche Leute zählen es zu den vernünftigen Sprachen]) und das alles nur, damit man keine neue Sprache lernen muß (wer programmieren kann, für den ist die Sprache egal)??
    Aber mal rein theoretisch betrachtet ist es möglich aus JS eine Win32 fähige Sprache zu basteln. Dazu würde man sich z.B. Mozilla als Source Code holen und dort die JS Engine rauslösen. Diese würde man dann um zusätzliche Funktionen, Objekte und Eigenschaften erweitern, so daß es möglich wird hier win32 Funktionen aufzurufen.
    1. Get people to play Space Taxi
    2. Sell real estates on neptun
    3. Profit!

    IE is not a browser, it is a scream.


    Outside of a dog, a book is man's best friend. Inside of a dog, it's too dark to read.

  4. #4
    Avatar von MOTH
    MOTH ist offline Haudegen
    registriert
    10-03-2002
    Ort
    Haan / DDorf
    Beiträge
    643
    alles klar dank' schön

  5. #5
    Bjoern ist offline Haudegen
    registriert
    05-04-2002
    Ort
    Berlin
    Beiträge
    507
    Beim Erweitern von Klassen gibt es ein Problem.

    Nehmen wir beispielsweise:

    function Obj(){
    this.value=new Array();
    }

    function test(){}
    test.prototype=new Obj();

    Dann haben alle Instanzen von test exakt die selben Eigenschaften, welche sie von Obj erben.
    Und mit die selben, meine ich die selben.

    a=new test()
    b=new test()

    alert(b.value==a.value)

    wird true zurückgeben. D. h. Änderungen an a.value würden auch b.value betreffen.

    Gibt es da andere Möglichkeiten?
    Diese Tatsache macht für mich das Erweitern von Klassen nutzlos.

  6. #6
    Avatar von Albu
    Albu ist offline Foren-Gott
    registriert
    04-07-2001
    Beiträge
    13.501
    Da es in JS keinen expliziten Konstrukt gibt, der die Vererbung einleitet, ist man auf die Vererbung durch prototype angewiesen. Richtig angewandt funktioniert sie auch.

    Code:
    Obj = function ()
    {
    	this.init ();
    }
    
    Obj.prototype.init = function  ()
    {
    	this.value = new Array ("xx");
    }
    
    function test()
    {
    	this.init ();
    }
    test.prototype = new Obj();
    Das Problem bei Deinem Beispiel ist die Tatsache, daß this.value = new Array (); nur ein einziges Mal aufgerufen wird und Du dardurch in allen Objekte immer auf die einzigste Instanz des Arrays zugreifst. Was Du aber brauchst, ist ein Array für jede abgeleitete Instanz.
    Die eigentlich überflüssige Instanz von Obj die in der Zeile test.prototype = new Obj(); immer erzeugt wird, ist dabei der Träger dieses gesharten Arrays. Was Du letztendlich gefunden hast, ist die Möglichkeit eine statische Variable zu definieren (sofern die Variable eine Referenz ist [d.h. Array, Objekt oder Klasseninstanz] und kein primitiver Datentyp).
    Normalerweise müßte man für test auch eine init Funktion definieren, die die notwendigen Initialisierungen für test übernimmt. Denn 1) könnte test wiederum eine Basisklasse für eine weitere abgeleitete Klasse sein und 2) wird durch die Anweisung test.prototype = new Obj(); die Klasse test "resettet" und man sollte (Variablen und) Funktionen _nach_ dieser Anweisung definieren.
    Allerdings wollte zumindest der Opera super anerkennen, um in meiner test.prototype.init per super.init () die Basisklasse aufzurufen. Entweder gibts das tatsächlich nicht, oder nur Opera mag es nicht. Für beide Fälle muß man sich eine geeignete Lösung ausdenken, denn Polymorhpie ist schon wichtig, und funktioniert in Actionscript problemlos. In JS sollte dies auch der Fall sein, die Syntax kann aber abweichen.
    1. Get people to play Space Taxi
    2. Sell real estates on neptun
    3. Profit!

    IE is not a browser, it is a scream.


    Outside of a dog, a book is man's best friend. Inside of a dog, it's too dark to read.

  7. #7
    Bjoern ist offline Haudegen
    registriert
    05-04-2002
    Ort
    Berlin
    Beiträge
    507
    Hmm...
    Also, irgendwie klappt das nicht.
    Ich gebe dir mal ein bisschen Code.
    Vielleicht fehlen ein paar Funktionen, aber die sind nicht wichtig.

    Die Basisklasse:

    PHP-Code:
    function canvas(){     
    this.init();     
    handleParas(this,canvas.arguments);      
    this.node=new createObj('div',this);     
    this.node.parent=this;  }

    addPrototypes(canvas.prototype,prototypes); 

    canvas.prototype.init=function(){
        
    this.backgroundColor='#e7e3de';    
        
    this.backgroundImage='none'
        
    this.border='none'
        
    this.color='black';  
        
    this.cursor='pointer';  
        
    this.height=0
        
    this.left=0
        
    this.margin=0;
        
    this.padding=0;
        
    this.position='absolute';
        
    this.overflow='hidden';
        
    this.top=0;  
        
    this.width=0;

    Die erweiterte Klasse:

    PHP-Code:
    function test(){
        
    handleParas(this,test.arguments);
        
    this.Position('absolute');
        
    this.Width('400px');
        
    this.Height('300px');
        
    this.BackgroundColor('blue');
        
    this.moveTo(this.left,80);
    }

    test.prototype=new canvas(); 
    Und nun zum Test:

    PHP-Code:
    a=new test(new Wleft(500));
    t=new test(new Wleft(50));

    alert(t.node==a.node); 
    Und, was kommt raus? True!

    Falls du dich wunderst, ich arbeite an einer Widget-Libary für Webdows6.
    Im Prinzip ist es das, was du mal vorgeschlagen hast.

    Noch Funktionen, die eigentlich nicht wichtig sind:

    PHP-Code:
    function createObj(type,styles)
      {
      var 
    obj=document.createElement(type);
      for(
    i in styles)
          {
          
    obj.style[i]=styles[i]; 
      }
      return 
    obj;
    }

    function 
    handleParas(object,arguments)
        {   
        var 
    i=0;
        while(
    arguments.length)
            {      
            
    object[arguments[i].typ]=arguments[i].value;
            
    i++;
        }
    }

    prototypes=new Object();
    prototypes.append=function(obj)
        {       
        if(!
    this.childs)
            {
            
    this.childs=new Array();
        }
        
    this.childs.push(obj);
        if(
    obj.node){
            
    this.node.appendChild(obj.node);
        }
        
    obj.parent=this;
    }    
    prototypes.appendChild=function(node)
        {       
        if(!
    this.childs)
            {
            
    this.childs=new Array();
        }
        
    this.childs.push(node);
        
    this.node.appendChild(node);
    }    
    prototypes.appendNode=function(node)
        {       
        if(!
    this.childs)
            {
            
    this.childs=new Array();
        }
        
    this.childs.push(node);
        
    node.parent=this;
    }         
    prototypes.BackgroundColor=function(para)
        {
        if(
    para)
            {
            
    this.node.style.backgroundColor=para;
        }
        else
            {
            return 
    this.node.style.backgroundColor;
        }
    }  
    prototypes.BackgroundImage=function(para)
        {
        if(
    para)
            {
            
    this.node.style.backgroundImage=para;
        }
        else
            {
            return 
    this.node.style.backgroundImage;
        }
    }      
    prototypes.Border=function(para)
        {
        if(
    para)
            {
            
    this.node.style.border=para;
        }
        else
            {
            return 
    this.node.style.border;
        }
    }       
    prototypes.Color=function(para)
        {
        if(
    para)
            {
            
    this.node.style.color=para;
        }
        else
            {
            return 
    this.node.style.color;
        }
    }                                         
    prototypes.CellPadding=function(para)
        {
        if(
    para)
            {
            
    this.node.cellPadding=para;
        }
        else
            {
            return 
    this.node.cellPadding;
        }
    }
    prototypes.CellSpacing=function(para)
        {
        if(
    para)
            {
            
    this.node.cellSpacing=para;
        }
        else
            {
            return 
    this.node.cellSpacing;
        }
    }
    prototypes.Cursor=function(para)
        {
        if(
    para)
            {
            
    this.node.style.cursor=para;
        }
        else
            {
            return 
    this.node.style.cursor;
        }
    }          
    prototypes.FontFamily=function(para)
        {
        if(
    para)
            {
            
    this.node.style.fontFamily=para;
        }
        else
            {
            return 
    this.node.style.fontFamily;
        }

    prototypes.Height=function(para)
        {
        if(
    para)
            {
            
    this.node.style.height=para;
        }
        else
            {
            return 
    this.node.style.height;
        }

    prototypes.Margin=function(para)
        {
        if(
    para)
            {
            
    this.node.style.margin=para;
        }
        else
            {
            return 
    this.node.style.margin;
        }

    prototypes.Left=function(para)
        {
        if(
    para)
            {
            
    this.node.style.left=para;
        }
        else
            {
            return 
    this.node.style.left;
        }

    prototypes.Padding=function(para)
        {
        if(
    para)
            {
            
    this.node.style.padding=para;
        }
        else
            {
            return 
    this.node.style.padding;
        }

    prototypes.Position=function(para)
        {
        if(
    para)
            {
            
    this.node.style.position=para;
        }
        else
            {
            return 
    this.node.style.position;
        }

    prototypes.tableBorder=function(para)
        {
        if(
    para)
            {
            
    this.node.border=para;
        }
        else
            {
            return 
    this.node.border;
        }

    prototypes.Top=function(para)
        {
        if(
    para)
            {
            
    this.node.style.top=para;
        }
        else
            {
            return 
    this.node.style.top;
        }

    prototypes.Width=function(para)
        {
        if(
    para)
            {
            
    this.node.style.width=para;
        }
        else
            {
            return 
    this.node.style.width;
        }

    prototypes.ZIndex=function(para)
        {
        if(
    para)
            {
            
    this.node.style.zIndex=para;
        }
        else
            {
            return 
    this.node.style.zIndex;
        }
    }  
    prototypes.positionTop=function(para)
        {
        if(
    para)
            {
            
    this.node.style.top=para;
        }
        else
            {
            return 
    this.node.style.top;
        }
    }
    prototypes.moveBy=function(x,y){
        
    this.moveTo(this.left-x,this.top-y);
    }

    prototypes.moveTo=function(x,y){ 
        
    this.left=this.node.style.left=x;
        
    this.top=this.node.style.top=y;
        


  8. #8
    Avatar von Albu
    Albu ist offline Foren-Gott
    registriert
    04-07-2001
    Beiträge
    13.501
    hmm also Dein Code hat immer noch den selben Fehler...

    Um es anders auszudrücken: Der Konstruktor der Basisklasse wird bei JS nicht automatisch aufgerufen, wenn eine abgeleitete Klasse instanziert wird. Was zur Folge hat, das this.node = new blah nur ein einziges Mal ausgeführt wird und Du damit Folgerichtig nur ein einizges Objekt erhälst, welches für alle Instanzen identisch ist. In C++ ist dies gleichbedeutend mit einer Klassen-Variable die als static definiert wird.

    Nachvollziehen kannst Du das in dem Du in jeden Constructor ein alert einbaust und Dir damit ausgeben läßt, welche Constructor wann ausgeführt wird.

    Also alles was mit new instanziert wird sollte nicht im Constructor einer Klasse, sondern in einer oder mehreren im Constructor aufrufbaren Funktionen durchgeführt werden, z.B. init (). Denn alle im Constructor erzeugten Objekte führen zu ungeahnten Nebeneffekten.

    Diese Unart ist eine Eigenheit der bei JS verwendeten Form der Vererbung. AS hat die gleichen Probleme, allerdings kann man dort mit super arbeiten. Vielleicht finde ich ja irgendwann das Pendant zu super in JS, damit das polymorphing hinhaut.
    1. Get people to play Space Taxi
    2. Sell real estates on neptun
    3. Profit!

    IE is not a browser, it is a scream.


    Outside of a dog, a book is man's best friend. Inside of a dog, it's too dark to read.

  9. #9
    Bjoern ist offline Haudegen
    registriert
    05-04-2002
    Ort
    Berlin
    Beiträge
    507
    Ah, jetzt habe ich es hingekriegt.

    Ich muss also im test-Construktor noch explizit den Konstruktor von canvas aufrufen.
    Nicht wirklich elegant, aber eine Lösung.

    danke

  10. #10
    Avatar von LaLALa
    LaLALa ist offline Routinier
    registriert
    26-08-2003
    Beiträge
    482
    @Bjoern
    Nur mal so:
    Steht bei deinen Codeangaben absichtlich Php drüber?
    Frag mich halt ob da das gleiche gillt....

  11. #11
    Microkotz ist offline Foren-Gott
    registriert
    01-12-2002
    Ort
    Germany --> Baden-Württemberg
    Beiträge
    2.240
    php steht nur deswegen drüber, weil dann das Forum syntax-highlighting für den Code aktiviert.
    Mit anderen Worten: Wenn PHP drüber steht, sind die schönen bunten Farben da.
    [size=1]Ehe == errare humanum est == irren ist Menschlich
    # define god root

  12. #12
    Avatar von .marc
    .marc ist offline Lebende Foren-Legende
    registriert
    26-12-2002
    Ort
    Schweiz / Biel
    Beiträge
    1.589
    Original geschrieben von Albu
    Was Du letztendlich gefunden hast, ist die Möglichkeit eine statische Variable zu definieren (sofern die Variable eine Referenz ist [d.h. Array, Objekt oder Klasseninstanz] und kein primitiver Datentyp).
    Was meinst du mit primitiven Datentyp? Denn undefined / null / false / true wird ebenfalls allen Instanzen einer Klasse zur Verfügung gestellt, was ja auch gut ist den sonst könnten diese Werte nicht überschrieben werden und das ganze "overriding" wäre futsch...
    Shit doesn't happen, it's produced by an asshole.
    brain-dump.org || Marc Tanner's web log

  13. #13
    Avatar von LaLALa
    LaLALa ist offline Routinier
    registriert
    26-08-2003
    Beiträge
    482
    achso dann fachsimpelt schön weiter

  14. #14
    Avatar von Albu
    Albu ist offline Foren-Gott
    registriert
    04-07-2001
    Beiträge
    13.501
    Original geschrieben von .marc
    Was meinst du mit primitiven Datentyp?
    Strings, Integer, Floats, Booleans, also die Standard Datentypen, die keine komplexen Objekte beinhalten und demzufolge nur als Referenz gespeichert werden (wie Arrays, Objekte und Klasseninstanzen).

    Beispiel:

    PHP-Code:
    function Obj()
    {
        
    this.value=true;
    }

    function 
    test() {};
    test.prototype=new Obj();

    a=new test();
    b=new test();

    a.value "xx";
    alert (a.value);
    alert (b.value); 
    Gibt bei mir im Opera (und IE) zwei unterschiedliche Werte aus, obwohl der Construktor von Obj nur einmal durchlaufen wird. Bei allem, was mit new instanziert werden muß, funktioniert das eben nicht.

    Original geschrieben von .marc
    Denn undefined / null / false / true wird ebenfalls allen Instanzen einer Klasse zur Verfügung gestellt, was ja auch gut ist den sonst könnten diese Werte nicht überschrieben werden und das ganze "overriding" wäre futsch...
    undefined, null, false und true sind ja auch reservierte Wörter in JS, d.h. sie werden vom System zur Verfügung gestellt. Und wenn mich nicht alles täuscht können sie nicht auf der linken Seite einer Zuweisung stehen, sie können also vom Programmierer nicht verändert werden (ist auch besser so).
    Das Overriding / Überschreiben einer Funktion in einer abgeleiteten Klasse hat damit aber irgendwie weniger zu tun. Außerdem scheitert es ein bißchen daran, daß man bei JS anscheinend keine Möglichkeit hat, um die Parent-Klasse aus einer überschriebenen Funktion aufzurufen.
    1. Get people to play Space Taxi
    2. Sell real estates on neptun
    3. Profit!

    IE is not a browser, it is a scream.


    Outside of a dog, a book is man's best friend. Inside of a dog, it's too dark to read.

  15. #15
    Avatar von .marc
    .marc ist offline Lebende Foren-Legende
    registriert
    26-12-2002
    Ort
    Schweiz / Biel
    Beiträge
    1.589
    Ich verstehe ehrlich gesagt denn Sinn deines Beispieles nicht, aber vielleicht hab ich wiedermal alles missverstanden. Das du zwei unterschiedliche Werte erhälst ist nachdem du einen in der Instanz definiert hast logisch, denn dieser "verdeckt" den Wert im prototypen.
    Ausserdem _kannst_ du String, Number und Boolean genauso wie Object und Array auch mit new instanzieren. var myString = "bla" ist also das Selbe wie var myString = new String("bla") genau wie myObject = {}; identisch mit myObject = new Object(); ist, so vermute ich es zumindest aber vielleicht kennst du ja einen Unterschied?
    PHP-Code:
    function Obj() 

        
    this.value=true


    function 
    test() {}; 
    test.prototype=new Obj(); 
    test.prototype.constructor test// Hinzugefügt weil der constructor sonst auf Obj zeigt

    a=new test(); 
    b=new test(); 

    alert (a.value); // true - vom prototypen
    alert (b.value); // true - vom prototypen

    a.value "xx"

    alert (a.value); // "xx" - von der Instanz
    alert (a.constructor.prototype.value// true - vom prototypen ist also noch da 
    alert (b.value); // true - vom prototypen

    delete a.value;

    alert (a.value); // true - vom prototypen
    alert (b.value); // true - vom prototypen 
    Wegen dem super hab ich ein bisschen rumprobiert, kann aber sein das folgendes kompletter Schwachsinn ist, also bitte korrigieren
    PHP-Code:
    myClass = function(){
        
    this.myArray = ["value"];
    }


    mySubClass = function(){
        
    this.constructor.prototype.constructor.call(this)
    }

    mySubClass.prototype = new myClass();

    myInstance1 = new mySubClass();
    myInstance2 = new mySubClass();

    alert(myInstance1.myArray == myInstance2.myArray// false

    // Würde gehen doch folgendes ergibt false
    alert(myInstance1.constructor == mySubClass// false
    // den der Konstruktor zeigt auf myClass
    alert(myInstance1.constructor == myClass// true
     
    // Man sollte also den constructor zurücksetzen und eine "super" - Eigenschaft erstellen

    myClass = function(){
        
    this.myArray = ["value"];
    }

    mySubClass = function(){
        
    this.mySuper.call(this)
    }

    mySubClass.prototype = new myClass();
    mySubClass.prototype.mySuper mySubClass.prototype.constructor;
    mySubClass.prototype.constructor mySubClass;

    myInstance1 = new mySubClass();
    myInstance2 = new mySubClass();

    alert(myInstance1.myArray == myInstance2.myArray// false
    alert(myInstance1.constructor == myClass// false
    alert(myInstance1.constructor == mySubClass// true 
    [ot /] Warum darf man Posts im FAQ - Forum nicht editieren?
    Shit doesn't happen, it's produced by an asshole.
    brain-dump.org || Marc Tanner's web log

Seite 1 von 2 12 LetzteLetzte

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •