wahsaga: Verständnisproblem bei OOP mit Javascript

Beitrag lesen

hi,

this.toString = function() { return this.hex+this.R+this.G+this.B; }


> Wofür braucht man das "this" vor "toString"? toString ist doch keine Methode von Farbe?!  
  
Das this davor braucht man, um toString zu einer privilegierten Methode zu machen, die von ausserhalb aufgerufen werden darf.  
  

> Aber jetzt sehe ich, dass im Beispiel von SELFHTML folgendes steht:  
>   
> ~~~javascript
  

> var Dezimalzahl = 15.5;  
> var Dualzahl = Dezimalzahl.toString(2);  
> 

Was ist an toString so besonders? toString() ist eine Methode des Number-Objekts. write() ist eine Funktion des window-Objekts. Die Methode write() ruft man per document.write() auf. Deswegen müsste man doch eigentlich toString() so aufrufen: number.toString(). Oder?

Nee, wenn schon Number.toString (Javascript ist case-sensitive).

Aber du willst ja hier nicht die Methode einer "Klasse" aufrufen, sondern die einer konkreten Klasseninstanz - und die trägt den Namen Dualzahl.
Also rufst du mit Dualzahl.toString() die Methode dieser Instanz auf - und die gibt dann in diesem Falle den Zahlwert mit zwei Nachkommastellen aus.

Ich habe irgendwie ziemlich große Probleme mit toString() :-)

Grundsätzlich wird die toString-Methode immer dann gebraucht, wenn ein Objekt in einem Kontext verwendet wird, der nach einem String verlangt.

alert("Wert: "+5);

alert gibt Strings aus, der Operator + für die Stringverkettung wird hier benutzt - und da 5 vom Typ Number ist, wird dessen toString-Methode aufgerufen, um aus 5 einen String zu machen, der sich mit "Wert: " verketten lässt. Sieht in diesem Falle nicht nach großem Tennis aus - passiert aber trotzdem :-)

Das 'Fertig' wird beim ersten Mal nicht ausgegeben, weil das Ausführen der Methode wegen dem return in der Zeile davor, schon abgebrochen wurde. Stimmt das?

Nein.
Wenn du nur Farbe() aufrufst, ist das ein stinknormaler Funktionsaufruf - Funktion läuft durch, und gibt mit return "Fertig" zurück.

Wenn du aber explizit new Farbe() verwendest, erzeugst du damit eine neue Instanz von Farbe. Rückgabe ist in diesem Falle die erzeugte Objektinstanz.
Und da _diese_ jetzt als Argument für alert benutzt wird, muss sie in einen String-Kontext gebracht werden - also wird ihre toString-Methode aufgerufen, und die gibt ganz explizit das Ergebnis des Ausdrucks this.hex+this.R+this.G+this.B zurück.

Kommentiere die Methode mal aus, und rufe dann noch mal
alert(new Farbe("E0", "FF", "E0"));

  • jetzt erhältst du nur eine Ausgabe [object] o.ä.
    Du hast keine eigene toString-Methode definiert - also wird die benutzt, die Farbe vom allgemeinen Typ Object geerbt hat - denn jede Funktion ist in javascript ja auch ein Object. Nur ist die leider so allgemein, dass sie von Farbe und dessen Eigenschaften nichts weiss - sie hat keine Ahnung, dass ein Objekt vom Typ Farbe die Eigenschaften R, G und B besitzt. Also kann sie auch keine detailiertere Auskunft über diese Objekt vom Typ Farbe geben, als dass es irgendwie vom Typ Object ist - und deshalb gibt sie nur [object] (o.ä., je nach Browser/Implementation ggf. etwas unterschiedlich) zurück, das ist alles, was sie darüber sagen kann.

Und warum wird beim Aufruf durch

alert(Farbe("E0", "FF", "E0"));


> nicht die Zeile  
>   
> ~~~javascript
  

> this.toString = function() { return this.hex+this.R+this.G+this.B; }  
> 

ausgeführt? Ok, ich weiß wieso. Weil eben beim Aufruf nicht new Farbe steht.

Weil Farbe hier nur einfach eine Funktion ist, die ausgeführt wird.
Da wird zwar irgendeiner Eigenschaft eine Funktionsreferenz zugewiesen - aber wen interessiert das in dem Moment? So eine Zuweisung erzeugt nichts "sichtbares" - es ist genau das gleiche, als hättest du irgendwo var foo = 5; notiert - schön, da wird ein Wert zugewiesen, kümmert aber in dem Moment niemanden wirklich.

Aber trotzdem habe ich es nicht verstanden. Warum interessiert sich JS nicht für diese Zeile. Ignoriert Javascript auch die folgenden Zeilen?

this.R = R;
this.G = G;
this.B = B;

  
Ignoriert werden sie nicht, während die Funktion abgearbeitet wird, werden da natürlich Zuweisungen gemacht.  
Aber der Rückgabewert der Funktion ist nur vom Typ String mit dem Inhalt "Fertig".  
this hat zwar innerhalb der Funktion auf diese gezeigt, die Eigenschaften konnten auch "angelegt" werden - aber du hast keinen Zugriff mehr darauf, weil alles was du zurückbekommst, "Fertig" ist.  
  

> Was mich auch verwirrt, aber eigentlich nichts mit OOP zutun hat ist die Methode [toString](http://de.selfhtml.org/javascript/objekte/number.htm#to_string). In SELFHTML heißt es:  
> ####  
> Wandelt eine Zahl in eine Zeichenkette (String) um.  
> ####  
> Es wird aber die Funktion new Farbe() aber mit diesen Parametern aufgerufen: "E0", "FF", "E0". Aber diese Parameter sind zwar Hexzahlen, aber für Javascript sind es doch Strings. Sie werden ja auch in Anführungszeichen übergeben. Also warum braucht man eine Methode, die Zahlen in Strings umwandelt, wenn man schon Strings hat?  
  
Vorsicht, die Stelle auf die du hier verweist, bezieht sich explizit auf das Number-Objekt.  
Wir haben aber ein selbstdefiniertes Objekt Farbe mit einer eigenen toString-Methode - das hat nicht das geringste mit Number zu tun.  
Und bei Farbe benutzen wir diese Methode jetzt ja nicht, um Zahlen in irgendwas zu verwandeln - sondern um die Werte der Eigenschaften hex, R, G und B miteinander zu verketten, und das als Ergebnis zurückzugeben - damit liefert uns unser Objekt vom Typ Farbe, welches einzelne (Farb-)Eigenschaften besitzt diese ganz praktisch in einer Form zurück, die wir sofort als Farbdefinition in bspw. Zuweisungen an CSS-Farbeigenschaften verwenden können.  
  
gruß,  
wahsaga  
  

-- 
/voodoo.css:  
#GeorgeWBush { position:absolute; bottom:-6ft; }