Beny: prototype und return werte

Hallo zusammen!

Habe ein bisschen mit Objekten und Vererbung herumgespielt und bin dabei auf folgende 2 Probleme gestossen, sicher kann mir das hier jemand erklären :)

  1. Wenn ich eine Funktion deklariere, diese mit prototype erweitere und dann ein Objekt erzeuge, erhalte ich beim Aufruf dieser Methode als Return-Wert den kompletten Funktionstext der Methode zurück.

also z. B.

function Hauptklasse ()
{
  this.x= new Array ("blabla", "dubidu");
}

Hauptklasse.prototype.ArrayNachString = function ()
{
  var tmp = "";
  for (var i=0; (i<this.x.length); i++)
  {
    tmp += this.x[i];
  }
  return tmp;
}

var TestObjekt = new Hauptklasse();
alert(TestObjekt.ArrayNachString);

->>> liefert mir den kompletten Quelltext der ArrayNachString function zurück... WARUM??? weil es eine Methode und keine Eigenschaft ist?

  1. Das Zweite Problem das ich habe, ist dass ich gerne in der Methode (hier ArrayNachString) die Variablen / Arrays der Hauptklasse verwenden würde, über "this" geht das aber anscheinend nicht. Gibt es so etwas wie eine "parent" Referenz oder muss ich das Parent-Objekt in diesem Fall immer über "this" zu den Methoden mitschleifen? Oder sind die Deklarationen einfach falsch? Ich würde gerne Eigenschaften deklarieren, die länger als nur eine einfache Wertzuweisung sind - wie macht man das am geschicktesten ohne jedesmal das Parentobjekt weiterreichen zu müssen?

Wäre supi-dankbar für jede Hilfestellung!

Beny

  1. Halihallo

    Habe ein bisschen mit Objekten und Vererbung herumgespielt und bin dabei auf folgende 2 Probleme gestossen, sicher kann mir das hier jemand erklären :)

    Hab durch deine Frage gleich selber noch was gelernt :-)

    ->>> liefert mir den kompletten Quelltext der ArrayNachString function zurück... WARUM??? weil es eine Methode und keine Eigenschaft ist?

    Eine Methode ist _nie_ eine Eigenschaft. Das sind zwei vollkommen verschiedene Dinge!

    Dein Fehler war: Die Zeichen '()' hinter ArrayNachString zu setzen, also:

    alert(TestObjekt.ArrayNachString());

    statt

    alert(TestObjekt.ArrayNachString);

    ...

    so einfach und doch so kompliziert kann es sein :-)
    JS fordert beim aufruf _jeder_ Funktion ein explizites () für die Parameter, ansonsten wird der Code der Funktion referenziert!

    1. Das Zweite Problem das ich habe, ist dass ich gerne in der Methode (hier ArrayNachString) die Variablen / Arrays der Hauptklasse verwenden würde, über "this" geht das aber anscheinend nicht.

    Sollte aber, sonst versteh ich kein OOP mehr... Entweder war das ein Folgefehler, oder ich verstehe deine Aussage nicht ganz.

    Gibt es so etwas wie eine "parent" Referenz oder muss ich das Parent-Objekt in diesem Fall immer über "this" zu den Methoden mitschleifen?

    Nein, es gibt kein Parent-Objekt (zumindest in deinem Fall nicht). Die Daten der Klassen-instanz werden über this angesprochen.
    Ein Parent-Objekt im weiten Sinn gibt es erst bei Vererbungen => Superklassen. Diese Daten werden dann aber in das 'this' "importiert". Das ist der ganze Sinn hinter Klassenvererbungen.

    Oder sind die Deklarationen einfach falsch?

    Nö. Die sind ganz OK. Aber das () hat dich aufgehängt :-)

    Ich würde gerne Eigenschaften deklarieren, die länger als nur eine einfache Wertzuweisung sind - wie macht man das am geschicktesten ohne jedesmal das Parentobjekt weiterreichen zu müssen?

    Wie meinst du das? - Kannst mir mal sagen, was du machen willst und wie dein Interface zur Klasse aussieht.

    Viele Grüsse

    Philipp

    1. Moin moin!

      ->>> liefert mir den kompletten Quelltext der ArrayNachString function zurück... WARUM??? weil es eine Methode und keine Eigenschaft ist?

      Das ist ganz normal so, auch fuer normale Funktionen, die keine Methoden eines Objektes sind. Bei jeder Variable/Eigenschaft, die kein primitiver Datentyp, sondern ein Objekt ist, und die in einem String-Kontext aufgerufen wird (wie in dem alert()), wird automatisch die toString()-Methode aufgerufen und deren Rueckgabewert verwendet. Diese Methode gibt es immer, da alle Objekte vom Objekt Object abstammen und toString bereits dort vorhanden ist.

      Objekte des Typs Function (alle Funktionen/Methoden sind Objekte dieses Typs) ueberschreiben diese Methode aber, naemlich so, dass der Quelltext der Funktion zurueckgeliefert wird. Dies stimmt sogar fuer eingebaute Funktionen, allerdings kommt dort nur die Ausgabe "[native code]", da es ja keinen JavaScript-Sourcecode dafuer gibt.

      Literatur:
        Object.toString: http://docserv.calocybe.dyndns.org/specs/NetscapeCommunications/JavaScript13ClientReference/object.htm#1193350
        Function.toString: http://docserv.calocybe.dyndns.org/specs/NetscapeCommunications/JavaScript13ClientReference/function.htm#1193615

      Eine Methode ist _nie_ eine Eigenschaft. Das sind zwei vollkommen verschiedene Dinge!

      Das ist ganz genau falsch rum. Eine Methode ist *immer* eine Eigenschaft. Es ist eine Eigenschaft von Typ Function. Man kann mit dieser Eigenschaft umgehen wie mit jeder anderen, d.h. insbesondere auch an andere Eigenschaften zuweisen, womit man dann zwei Methoden hat, die dasselbe tun.

      alert(TestObjekt.ArrayNachString());

      Das ruft die Methode auf und zeigt ihren Rueckgabewert an.

      alert(TestObjekt.ArrayNachString);

      Das ruft automatisch die Methode toString() des Function-Objektes auf (also TestObjekt.ArrayNachString.toString()), da alert() einen String-Kontext vorgibt.

      1. Das Zweite Problem das ich habe, ist dass ich gerne in der Methode (hier ArrayNachString) die Variablen / Arrays der Hauptklasse verwenden würde, über "this" geht das aber anscheinend nicht.

      Sollte aber, sonst versteh ich kein OOP mehr... Entweder war das ein Folgefehler, oder ich verstehe deine Aussage nicht ganz.

      Geht mir auch so. Der Code sieht fuer mich ok aus. Vielleicht sollte Beny uns was ueber evtl. auftretende Fehlermeldungen erzaehlen?

      Gibt es so etwas wie eine "parent" Referenz oder muss ich das Parent-Objekt in diesem Fall immer über "this" zu den Methoden mitschleifen?

      Sowas aehnliches gibt es. Heisst __proto__, und zum Verstaendnis solltest Du Dir vielleicht http://docserv.calocybe.dyndns.org/specs/NetscapeCommunications/JavaScript13ClientGuide/obj2.htm durchlesen. Sollte aber fuer diesen Fall eigentlich nicht notwendig sein.

      Nein, es gibt kein Parent-Objekt (zumindest in deinem Fall nicht). Die Daten der Klassen-instanz werden über this angesprochen.

      Die Begriffe Klasse und Instanz gibt es in JavaScript so nicht, da JS keine klassenbasierte Sprache ist, sondern Prototypbasiert. IMHO ein wirklich beklopftes Konzept, aber wenn es Dich genau interessiert, siehe obigen Link.

      So long

      --
      Falscher oder fehlender Kaffee. Benutzer angehalten.

      1. Halihallo Calocybe

        ->>> liefert mir den kompletten Quelltext der ArrayNachString function zurück... WARUM??? weil es eine Methode und keine Eigenschaft ist?

        Das ist ganz normal so, auch fuer normale Funktionen, die keine Methoden eines Objektes sind. Bei jeder Variable/Eigenschaft, die kein primitiver Datentyp, sondern ein Objekt ist, und die in einem String-Kontext aufgerufen wird (wie in dem alert()), wird automatisch die toString()-Methode aufgerufen und deren Rueckgabewert verwendet. Diese Methode gibt es immer, da alle Objekte vom Objekt Object abstammen und toString bereits dort vorhanden ist.

        So lautet die Theorie zur Praxis, Beny :-)

        Objekte des Typs Function (alle Funktionen/Methoden sind Objekte dieses Typs) ueberschreiben diese Methode aber, naemlich so, dass der Quelltext der Funktion zurueckgeliefert wird. Dies stimmt sogar fuer eingebaute Funktionen, allerdings kommt dort nur die Ausgabe "[native code]", da es ja keinen JavaScript-Sourcecode dafuer gibt.

        Schade eigentlich, hätte gerne gewusst, wie document.write() intern funktioniert...

        Eine Methode ist _nie_ eine Eigenschaft. Das sind zwei vollkommen verschiedene Dinge!

        Das ist ganz genau falsch rum. Eine Methode ist *immer* eine Eigenschaft. Es ist eine Eigenschaft von Typ Function. Man kann mit dieser Eigenschaft umgehen wie mit jeder anderen, d.h. insbesondere auch an andere Eigenschaften zuweisen, womit man dann zwei Methoden hat, die dasselbe tun.

        Ja, da hast du selbstverständlich recht. Anscheinend muss ich die grundlegenden Begriffe von OOP mal lernen :-)

        1. Das Zweite Problem das ich habe, ist dass ich gerne in der Methode (hier ArrayNachString) die Variablen / Arrays der Hauptklasse verwenden würde, über "this" geht das aber anscheinend nicht.

        Sollte aber, sonst versteh ich kein OOP mehr... Entweder war das ein Folgefehler, oder ich verstehe deine Aussage nicht ganz.

        Geht mir auch so. Der Code sieht fuer mich ok aus. Vielleicht sollte Beny uns was ueber evtl. auftretende Fehlermeldungen erzaehlen?

        Entweder das, oder mal sagen, ob diese Frage noch aktuell ist. Ich habe nämlich das gefühl, das sie bereits aus dem Kontext beantwortet wurde. Wenn nicht: Beny: Schau mal bei google rein mit den Keywords JavaScript und OOP, da wirst du geholfen :-)

        Gibt es so etwas wie eine "parent" Referenz oder muss ich das Parent-Objekt in diesem Fall immer über "this" zu den Methoden mitschleifen?

        Nein, es gibt kein Parent-Objekt (zumindest in deinem Fall nicht). Die Daten der Klassen-instanz werden über this angesprochen.

        Die Begriffe Klasse und Instanz gibt es in JavaScript so nicht, da JS keine klassenbasierte Sprache ist, sondern Prototypbasiert. IMHO ein wirklich beklopftes Konzept, aber wenn es Dich genau interessiert, siehe obigen Link.

        Ich werde mir deine Links auf jeden Fall mal ansehen, obwohl ich alles andere, als ein JS-Programmierer bin...

        Falscher oder fehlender Kaffee. Benutzer angehalten.

        Du bringst mich da grad auf eine gute Idee. Los, an die Kaffemaschine. Ich muss fit werden, wird heute wieder ein langer Abend :-)
        Gestern habe ich ca. 7dl Kaffee getrunken... Meine Güte, hat mein Magen sich gemeldet (aber jetzt ist das Bauchweh weg und alles beginnt von vorne) :-))

        Viele Grüsse

        Philipp

        1. Re there!

          So lautet die Theorie zur Praxis, Beny :-)

          Yoh, ich hoffe, mit dem Beispiel weiter unten war es trotzdem verstaendlich. ;-)

          Schade eigentlich, hätte gerne gewusst, wie document.write() intern funktioniert...

          Hehe, genau das hab ich mir auch immer gedacht. *g*

          Eine Methode ist _nie_ eine Eigenschaft. Das sind zwei vollkommen verschiedene Dinge!

          Das ist ganz genau falsch rum.

          Ja, da hast du selbstverständlich recht. Anscheinend muss ich die grundlegenden Begriffe von OOP mal lernen :-)

          Aehm, vom Standpunkt der (richtigen) OOP haettest Du schon Recht gehabt. Methoden und Eigenschaften sind tatsaechlich zwei verschiedenen Sachen. Mein Einwand bezog sich nur auf JS, wo das dasselbe ist. Andere Programmiersprachen unterscheiden das sehr wohl.

          Du bringst mich da grad auf eine gute Idee. Los, an die Kaffemaschine. Ich muss fit werden, wird heute wieder ein langer Abend :-)

          Jetzt noch? *g*

          Gestern habe ich ca. 7dl Kaffee getrunken... Meine Güte, hat mein Magen sich gemeldet (aber jetzt ist das Bauchweh weg und alles beginnt von vorne) :-))

          7dl im Sinne von 700ml? Mann mann, Du schonst Dich ja nicht gerade. Aber wenn der Magen spinnt, gibt's nur eins, naemlich ein paar Bier draufschuetten, dann entspannt sich alles wieder. Apropos, werde gleich mal loslegen... *g*

          So long

          --
          From the programmer's point of view the user is just a peripheral that types when you issue a read request.

          1. Re: Halihallo

            So lautet die Theorie zur Praxis, Beny :-)

            Yoh, ich hoffe, mit dem Beispiel weiter unten war es trotzdem verstaendlich. ;-)

            Das wars. Du hast ja lediglich die Theorie zu meiner Praxis beschrieben. Somit haben wir alles gesagt und auch verständlich! - Deine Theorie war verständlich, das habe ich gar nicht kritisiert... :-)

            Eine Methode ist _nie_ eine Eigenschaft. Das sind zwei vollkommen verschiedene Dinge!

            Das ist ganz genau falsch rum.

            Ja, da hast du selbstverständlich recht. Anscheinend muss ich die grundlegenden Begriffe von OOP mal lernen :-)

            Aehm, vom Standpunkt der (richtigen) OOP haettest Du schon Recht gehabt. Methoden und Eigenschaften sind tatsaechlich zwei verschiedenen Sachen. Mein Einwand bezog sich nur auf JS, wo das dasselbe ist. Andere Programmiersprachen unterscheiden das sehr wohl.

            Und ich dachte schon, dass ich kein OOP mehr verstehe :-)

            Du bringst mich da grad auf eine gute Idee. Los, an die Kaffemaschine. Ich muss fit werden, wird heute wieder ein langer Abend :-)

            Jetzt noch? *g*

            Wohl eher "noch immer" :-)
            S'ist heut schon meine zweite Kanne :-)

            Gestern habe ich ca. 7dl Kaffee getrunken... Meine Güte, hat mein Magen sich gemeldet (aber jetzt ist das Bauchweh weg und alles beginnt von vorne) :-))

            7dl im Sinne von 700ml?

            Genau das :-)

            Mann mann, Du schonst Dich ja nicht gerade.

            Ich bin noch jung (21) und kann's mir leisten :-)
            Aber der "fast" regelmässige Aufenthalt im Training Center und die Massagen machen schon einiges wieder wet :-)

            Aber wenn der Magen spinnt, gibt's nur eins, naemlich ein paar Bier draufschuetten, dann entspannt sich alles wieder. Apropos, werde gleich mal loslegen... *g*

            Genau meine Meinung... :-)
            Trink doch bitte noch ein paar für mich... Leider muss ich heute noch bei klarem Verstand sein, sonst würde ich deinem Beispiel liebend gern folgen... :-)
            Obwohl: Programmieren im angetrunkenen Zustand ist auch ganz lustig, nur eben nicht so effizient... Aber nach einer Party mache ich mir oft einen Spass daraus und programmiere irgendwelchen Stuss, nur um zu schaun, ob ich's noch hinkriege... Aber bei der siebten Vererbung von irgendwelchen Klassen, streikt dann mein Kurzzeitgedächtnis und sagt: "hör endlich auf zu programmieren und trink lieber noch eins, das kannst du im Moment nämlich wesentlich besser". *g*

            Viele Grüsse vom Bodensee (vielleicht noch ganz unten auf der D-Karte verzeichnet)

            Philipp

            1. Moin!

              Na, wieder wach nach so viel Kaffee?? ;-) Ich bin echt platt, habe die Frage Samstag nacht gepostet und gleich so ein thread... ihr seid echt hardcore drauf!! Tausend Dank!
              Werde mir das jetzt mal ganz genau anschauen und wenn ichs dann immer noch nicht begriffen habe (...) weiss ich ja, wo ich euch finde :)

              Cheerios, Beny