portseven: Objekt in Objekt wird nicht angezeigt

Tag,

bin grad dabei bisschen Javascript zu lernen. Jetzt wollte ich mal Fragen warum nur ein Objekt angezeigt wird und nicht das andere.

Es wird nur Farbe und Geschwindigkeit angezeigt, der Rest nicht.

	<script>
		function Motor(l, z, k)
		{
			this.leistung = 1;
			this.zylinder = z;
			this.kraftstoff = k;
			this.tunen = motorTunen;
			this.toString = motorAusgeben;
		}
		
		function motorTunen(x)
		{
			this.leistung += x;
		}
		
		function motorAusgeben()
		{
			return "Leistung: " + this.leistung + ", Zylinder: " + this.zylinder + ", Kraftstoff: " + this.kraftstoff;
		}
		
		function Fahrzeug(f, g)
		{
			this.farbe = f;
			this.geschwindigkeit = g;
			this.toString = fahrzeugAusgeben;
		}
		
		function fahrzeugAusgeben()
		{
			return "Farbe: " + this.farbe + ", Geschwindigkeit: " + this.geschwindigkeit;
		}
	</script>
	
	<script>
	
	var dacia = new Fahrzeug("Silber", 50, new Motor(60, 4, "Diesel"));
	document.write(dacia + "<br>");

	</script>
  1. Tach!

    bin grad dabei bisschen Javascript zu lernen. Jetzt wollte ich mal Fragen warum nur ein Objekt angezeigt wird und nicht das andere.

    Es wird nur Farbe und Geschwindigkeit angezeigt, der Rest nicht.

    Fahrzeug.toString() macht nur das, was du mit der Funktion fahrzeugAusgeben überschrieben hast. Da passiert nicht noch automagisch was anderes.

    document.write(dacia + "<br>");

    Für Debug-Ausgaben besser console.log() verwenden. Die Konsole hat man ja beim Entwickeln immer offen - sollte man zumindest haben.

    dedlfix.

    1. @@dedlfix

      Für Debug-Ausgaben besser console.log() verwenden. Die Konsole hat man ja beim Entwickeln immer offen - sollte man zumindest haben.

      Sollte man? Und dann übersieht man, dass die Seite bei Nutzern nicht funktioniert‽

      Es gibt Bugs in Browsern, die nur dann auftreten, wenn das Entwicklertool nicht geöffnet ist: Firefox bug: custom property for generated content set with JavaScript (Thread hier im Forum).

      LLAP 🖖

      --
      „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
      1. Tach!

        Für Debug-Ausgaben besser console.log() verwenden. Die Konsole hat man ja beim Entwickeln immer offen - sollte man zumindest haben.

        Sollte man? Und dann übersieht man, dass die Seite bei Nutzern nicht funktioniert‽

        Ein kompromissloses Argument‽

        Es gibt Bugs in Browsern, die nur dann auftreten, wenn das Entwicklertool nicht geöffnet ist: Firefox bug: custom property for generated content set with JavaScript (Thread hier im Forum).

        Wegen solcher Bugs die Konsole geschlossen zu halten ist, wäre jedenfalls die falscheste Entscheidung, die man treffen könnte. Die Konsole ist weiterhin ein Werkzeug, das sehr gute Dienste beim Entwickeln und bei der Fehlersuche leistet. Gerade wenn man als Anfänger noch ungeübt ist und die Zeichen der Browser, wie beispielsweise leere oder abgebrochene Ausgabe, noch nicht so gut deuten kann. Natürlich wird man die Seite mal mit und mal ohne geöffnete Entwicklertools testen. Fehlermeldungen in der Konsole zu finden erspart einem deutlich mehr Zeit als einzelne Browserbugs kosten. Du hast da mal einen Fehler gefunden und stellst nun das ganze Werkzeug infrage?

        dedlfix.

        1. @@dedlfix

          Natürlich wird man die Seite mal mit und mal ohne geöffnete Entwicklertools testen.

          Darauf wollte ich hinaus. Das ist was ganz anderes als das, was du vorher sagtest:

          Für Debug-Ausgaben besser console.log() verwenden. Die Konsole hat man ja beim Entwickeln immer offen - sollte man zumindest haben.

          (Und damit hier keine Missverständnisse aufkommen: Testen ist Teil des Entwickelns.)

          Du hast da mal einen Fehler gefunden und stellst nun das ganze Werkzeug infrage?

          Natürlich nicht. Wie kommst du darauf?

          (Und derjenige, der dir hier einen Anti-Gunnar-Punkt zugeschanzt hat, hat das auch nicht durchschaut.)

          LLAP 🖖

          --
          „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
          1. Hallo Gunnar Bittersmann,

            (Und derjenige, der dir hier einen Anti-Gunnar-Punkt zugeschanzt hat, hat das auch nicht durchschaut.)

            Derjenige war ich. Und ich denke a) schon, dass ich das durchschaut habe und vergebe b) keine Anti-Personen-Punkte.

            Bis demnächst
            Matthias

            --
            Rosen sind rot.
            1. @@Matthias Apsel

              Derjenige war ich. Und ich denke a) schon, dass ich das durchschaut habe

              Dann verstehe ich den Punkt nicht.

              Ich sagte: nicht ausschließlich mit geöffnetem Entwicklerwerkzeug testen, weil …

              dedlfix sagte: na dann eben nicht ausschließlich mit geöffnetem Entwicklerwerkzeug testen. Und unterstellte, ich würde das Entwicklerwerkzeug infrage stellen, was überhaupt nicht der Fall war.

              Wofür bekam dedlfix den Punkt?

              LLAP 🖖

              --
              „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
              1. Hallo Gunnar Bittersmann,

                Wofür bekam dedlfix den Punkt?

                für

                die Konsole geschlossen zu halten ist, wäre jedenfalls die falscheste Entscheidung, die man treffen könnte. Die Konsole ist weiterhin ein Werkzeug, das sehr gute Dienste beim Entwickeln und bei der Fehlersuche leistet. Gerade wenn man als Anfänger noch ungeübt ist und die Zeichen der Browser, wie beispielsweise leere oder abgebrochene Ausgabe, noch nicht so gut deuten kann. Natürlich wird man die Seite mal mit und mal ohne geöffnete Entwicklertools testen. Fehlermeldungen in der Konsole zu finden erspart einem deutlich mehr Zeit

                Bis demnächst
                Matthias

                --
                Rosen sind rot.
              2. Hallo,

                Ich sagte: nicht ausschließlich mit geöffnetem Entwicklerwerkzeug testen, weil …

                Nein, sagtest du nicht. Du fragtest „Sollte man?“…
                Wenn man sich für Ellipsen entscheidet, sollte man damit rechnen, missverstanden zu werden!

                Gruß
                Kalk

          2. Tach!

            Natürlich wird man die Seite mal mit und mal ohne geöffnete Entwicklertools testen.

            Darauf wollte ich hinaus. Das ist was ganz anderes als das, was du vorher sagtest:

            Für Debug-Ausgaben besser console.log() verwenden. Die Konsole hat man ja beim Entwickeln immer offen - sollte man zumindest haben.

            Ja, weil ich nicht meinte, gezielt mit und ohne zu testen. Ich deaktiviere sie eher, weil sie Platz wegnehmen, wenn ich die Seite als solche und nicht deren Javascript-Funktionalität bearbeite.

            Du hast da mal einen Fehler gefunden und stellst nun das ganze Werkzeug infrage?

            Natürlich nicht. Wie kommst du darauf?

            Zumindest hast du meine Aussage infrage gestellt, und die bezog sich auf die Vorgehensweise. Das las sich für mich so, als ob du also genau diese Vorgehensweise mit dem Tool als generell fragwürdig ansiehst. Das hielt ich für unangemessen, besonders weil du als Begründung lediglich ein Fehler in einer ganz besonderen Situation angeführt hast. Angemessen hätte ich es dann gefunden, wenn die Entwicklertools generell defekt wären und mehr Schaden als Nutzen anrichten. Angemessen hätte ich deine Aussage auch gefunden, wenn du das lediglich ergänzend als beachtenswert und nicht als Kontrastpunkt formuliert hättest.

            (Und derjenige, der dir hier einen Anti-Gunnar-Punkt zugeschanzt hat, hat das auch nicht durchschaut.)

            Liegt wohl daran, dass es nicht so ganz verständlich war, was du eigentlich aussagen wolltest.

            dedlfix.

            1. @@dedlfix

              Zumindest hast du meine Aussage infrage gestellt, und die bezog sich auf die Vorgehensweise. Das las sich für mich so, als ob du also genau diese Vorgehensweise mit dem Tool als generell fragwürdig ansiehst.

              Ich wollte mich auf das „immer“ in

              Für Debug-Ausgaben besser console.log() verwenden. Die Konsole hat man ja beim Entwickeln immer offen - sollte man zumindest haben.

              beziehen. Wegen: sollte man nicht immer offen haben.

              Vielleicht hab ich zuviel stehenlassen und es wäre ohne „Für Debug-Ausgaben besser console.log() verwenden“ verständlicher gewesen?

              LLAP 🖖

              --
              „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
  2. Hey,

    	
    		function Fahrzeug(f, g)
    		{
    			this.farbe = f;
    			this.geschwindigkeit = g;
    			this.toString = fahrzeugAusgeben;
    		}
    		
    	var dacia = new Fahrzeug("Silber", 50, new Motor(60, 4, "Diesel"));
    	document.write(dacia + "<br>");
    

    Ich würde mal vermuten, dass liegt daran, das Fahrzeug kein dritten Parameter erwartet und nichts mit dem neuen Motor anzufangen weiß.

    Gruß
    Jo

  3. Lieber portseven,

    warum machst Du das so?

    		function Motor(l, z, k)
    		{
    			this.leistung = 1;
    			this.zylinder = z;
    			this.kraftstoff = k;
    			this.tunen = motorTunen;
    			this.toString = motorAusgeben;
    		}
    		
    		function motorTunen(x) { ... }
    		function motorAusgeben() { ... }
    

    Ich hätte jetzt erwartet, dass Du entweder so vorgehst...

    function Motor (l, z, k) {
      this.leistung = 1;
      this.motorTunen = function () { ... };
      this.motorAusgeben = function () { ... };
    }
    

    ... oder so:

    function Motor (l, z, k) {
      this.leistung = 1;
    }
    
    Motor.prototype.motorAusgeben = function () { ... };
    

    Ich bin mir jetzt nicht sicher, ob in Deiner Variante innerhalb von motorAusgeben das Schlüsselwort this auf das Motor-Objekt verweist, oder nicht. In den von mir skizzierten Schreibweisen kann ich es aber garantieren...

    Liebe Grüße,

    Felix Riesterer.

    1. Weil das so in einem Buch steht, das ich grad lese.

      Wie gesagt ich lerne es zurzeit & hab auch derzeit keine große Erfahrung.

      Vielen Dank für eure Hilfe werde mal bisschen rumtesten.

    2. Hallo Felix

      Ich bin mir jetzt nicht sicher, ob in Deiner Variante innerhalb von motorAusgeben das Schlüsselwort this auf das Motor-Objekt verweist, oder nicht.

      Worauf this innerhalb von motorAusgeben zeigt hängt von der Art des Aufrufs ab, nicht davon, wie die Funktion definiert wurde.

      // direct call expression
      
      motorAusgeben();
      

      Bei einem normalen Funktionsaufruf zeigt this auf window, oder undefined, wenn das Skript im Strict Mode ausgeführt wird. In einem Modul ist this bei einem gewöhnlichen Aufruf standardmäßig undefined.

      // via member expression
      
      const motor = new Motor;
      
      motor.motorAusgeben();
      

      Wird eine Funktion über einen Elementausdruck als Methode eines Objektes aufgerufen, dann enthält this eine Referenz auf eben dieses Objekt. Das entspricht dem Folgenden Aufruf mit call, bei dem die Referenz explizit übergeben wird.

      // provide function context explicitly
      
      const motor = new Motor;
      
      motorAusgeben.call(motor);
      

      Dass im vorliegenden Programm Object.prototype.toString überschrieben wird ändert an all dem nichts. Eine Methode ist nur eine Dateneigenschaft und der Wert eine Referenz auf die in diesem Fall außerhalb des Konstruktors definierte Funktion.

      function Motor() {
        this.toString = motorAusgeben;
      }
      
      // trigger implicit toString call
      
      document.body.append(new Motor);
      

      Wird das Objekt in einen Kontext gebracht in der ein String erwartet wird, dann wird nach einer Methode toString gesucht, erst auf dem Objekt selbst und dann in seiner Prototypenkette.

      In diesem Fall wird bereits auf der Instanz eine entsprechende Eigenschaft gefunden, die Referenz aufgelöst und dann die Funktion motorAusgeben im Kontext der Instanz aufgerufen.

      // Delegate method to prototype
      
      Motor.prototype.toString = function () { /* ... * / };
      

      Die Methode unter dem Eigenschaftsnamen motorAusgeben zu definieren so wie du es vorgeschlagen hast wäre im Hinblick auf das offenbar gewünschte Verhalten nicht sinnvoll, die Methode unter dem Namen toString auf dem Prototyp zu definieren hingegen schon.

      Die Funktion motorAusgeben ist inhaltlich eng mit der Klasse Motor verknüpft, folglich ist es sinnvoll sie auch auf Motor.prototype zu definieren um diese Verbindung auch nach außen sichtbar zu machen.

      // same as Motor.prototype.toString.call(motor);
      
      const motor = new Motor;
      
      motor.toString();
      

      Bei einem Aufruf auf einer Instanz von Motor wird toString nun nicht mehr über das Objekt selbst sondern über seinen Prototypen referenziert. Die Kontextvariable this zeigt in diesem Fall wie du schon sagtest dennoch auf die Instanz.

      Viele Grüße,

      Orlok

  4. Hi,

    		function Motor(l, z, k)
    		{
    			this.leistung = 1;
    

    hier zeigt sich, warum ein einzelnes kleines Ell ungeeignet ist als Variablenname. Wird zu leicht mit einer 1 verwechselt. Das Syntaxhighlighting hier verrät es …

    		function fahrzeugAusgeben()
    		{
    			return "Farbe: " + this.farbe + ", Geschwindigkeit: " + this.geschwindigkeit;
    		}
    

    Wie soll der Motor ausgegeben werden, wenn da nichts dafür gemacht wird? Es wird nur Farbe und Geschwindigkeit ausgegeben.

    	function Fahrzeug(f, g)
    		{
    			this.farbe = f;
    			this.geschwindigkeit = g;
    		this.toString = fahrzeugAusgeben;
     	}
    
    	var dacia = new Fahrzeug("Silber", 50, new Motor(60, 4, "Diesel"));
    	document.write(dacia + "<br>");
    

    Du übergibt einen Motor (3. Parameter) an das Fahrzeug, aber das Fahrzeug ist umweltfreundlich und will gar keinen Motor haben (der Konstruktor hat nur 2 Parameter), und baut ihn schon gar nicht ein (keine Zuweisung an eine Eigenschaft).

    cu,
    Andreas a/k/a MudGuard