af2111: Problem mit NaN

Hallo,

ich habe(zu Testzwecken) eine Seite mit der Prototype Inheritance programmiert. Dabei wollte ich ein Programm schreiben, welches das Alter eines Studenten jede Sekunde erhöht. Wenn der Student 8 Jahre( also 8 Sekunden) auf der Uni war, soll ein Alert mit der Benachrichtung zum Doktortitel im jeweiligen Fach kommen. Währenddessen soll ein Counter in der Konsole die Zeit hochzählen. Aber leider wird statt jede Sekunde eine Zahl hochgezählt, sondern es kommt die Meldung "NAN".

Hier der Code:

let student = {
    getFullname: function () {
        alert("Er heißt " + this.firstname + " " + this.lastname);
    },
    altern: function () {
        let erstsemesterAlter = this.alter;
        setInterval(function () {
            this.alter = this.alter + 1;

            if (this.alter - erstsemesterAlter == 8) {
                alert("Doktor in " + this.Fach + "!!!");
            }
        }, 1000);
    }


}

let max = {
    firstname: "Max",
    lastname: "Mustermann",
    Fach: "Informatik",
    alter: 23
};
max.__proto__ = student;
console.log(max);

max.altern();

Hat jemand eine Idee, wieso die Variable this.alter nicht als Nummer gezählt wird?

  1. Hi,

        altern: function () {
            let erstsemesterAlter = this.alter;
            setInterval(function () {
                this.alter = this.alter + 1;
    

    this in der function altern ist was anderes als das this in der function im setInterval.

    Damit ist auch this.alter jeweils was anderes.

    Das this.alter, das hochgezählt wird, wurde vorher nicht initialisiert.

    cu,
    Andreas a/k/a MudGuard

    1. Danke für den Tipp,

      habe das Problem jetzt gelöst. Hier ist der Code:

      let student = {
       
          getFullname: function () {
              alert("Er heißt " + this.firstname + " " + this.lastname);
          },
          altern: function () {
              let erstsemesterAlter = this.alter;
              let funktionsalter = this.alter;
              let funktionsfach = this.Fach;
              console.log(erstsemesterAlter);
              setInterval(function () {
                 
                  funktionsalter = funktionsalter + 1;
                  console.log(funktionsalter);
                  if (funktionsalter - erstsemesterAlter == 8) {
                      alert("Doktor in " + funktionsfach + "!");
                    
                  }
              }, 1000);
          }
      
      
      }
      
      let max = {
          firstname: "Max",
          lastname: "Mustermann",
          Fach: "Informatik",
          alter: 23
      };
      
      let lea = {
          firstname: "Lea",
          lastname: "Mustermann",
          Fach: "Mathematik",
          alter: 19
      };
      max.__proto__ = student;
      lea.__proto__ = student;
      
      
      lea.altern();
      
      1. Hallo af2111,

        das ist nicht gut. Du möchtest das Alter des Studenten ändern. Aber dein Timer ändert nur noch eine lokale Variable.

        Korrekt ist, das this-Problem zu lösen. Wie schon erklärt, wird this bei einem Funktionsaufruf an den Aufrufkontext gebunden. Bei einem Methodenaufruf ist das das Objekt, bei einem Funktionsaufruf aus settimeout ist das - im strict mode - null. Um das zu umgehen, hast Du zwei Möglichkeiten.

        (1) Prä-ECMAScript 2015: Du erstellst eine Variable, der Du this zuweist. So eine Variable nennt man gerne self oder that. Im settimeout callback verwendest Du dann self bzw. that.

        (2) ECMAScript 2015 Lösung: Du verwendest eine Arrow-Funktion. Arrow-Funktionen unterscheiden sich von normalen Funktionen dadurch, dass sie this nicht binden, d.h. innerhalb der Arrow-Funktion hast Du das gleiche this zur Verfügung wie außerhalb. Arrow-Funktionen wurden genau wie let mit ECMAScript 2015 eingeführt. Du nutzt let, also kannst Du auch Arrow-Funktionen nutzen. Der Unterschied in der Syntax ist minimal:

        altern: function () {
                let erstsemesterAlter = this.alter;
                setInterval(() => {
                    this.alter = this.alter + 1;
        
                    if (this.alter - erstsemesterAlter == 8) {
                        alert("Doktor in " + this.Fach + "!!!");
                    }
                }, 1000);
            }
        

        Rolf

        --
        sumpsi - posui - clusi
        1. Okay,

          danke für den Tipp.

          Ich habe das Problem jetzt so gelöst:

          let student = {
          
              getFullname: function () {
                  alert("Er heißt " + this.firstname + " " + this.lastname);
              },
              altern: function () {
                  let erstsemesterAlter = this.alter;
                  let that = this;
          
                  console.log(erstsemesterAlter);
                  setInterval(function () {
          
                      that.alter = that.alter + 1;
                      console.log(that.alter);
                      if (that.alter - erstsemesterAlter == 8) {
                          alert("Doktor in " + that.Fach + "!");
          
                      }
                  }, 1000);
              }
          
          
          }
          
          let max = {
              firstname: "Max",
              lastname: "Mustermann",
              Fach: "Informatik",
              alter: 23
          };
          
          let lea = {
              firstname: "Lea",
              lastname: "Mustermann",
              Fach: "Mathematik",
              alter: 19
          };
          max.__proto__ = student;
          lea.__proto__ = student;
          
          
          lea.altern();