Hallo,
ich bin gerade dabei, ein Programm in JS zu programmieren, und wie bei
jedem Projekt muss man irgendwann mal debuggen. Also alles feini, feini
gedebuggt, das Problem ist nur:
Wenn ich das Programm durchsteppe, kommt die richtige Ausgabe (für
Debugging-Zwecke), die Variable hat auch den erwarteten und richtigen
Wert, wenn ich das Programm allerdings so durchlaufen lasse, kommt was
falsches bei rum.
Kann mir eventuell jemand einen Tipp geben, oder wenigstens ein
Suchbegriff, weil ich auch nicht wirklich weiß, wonach ich suchen soll.
Ist das ein bekannter Bug in Firefox oder mein Fehler?
Schonmal vielen Dank im Vorraus!
PS: Ich habe Linux Mint 19 Cinnamon 64 Bit mit Firefox 63.0 Quantum
Was ich noch vergessen habe:
Wenn ich einen Breakpoint auf die console.log()-Zeile setze und über die
Variable hover, wird mir der richtige Wert angezeigt, aber der falsche
ausgegeben.
Mit anderen Worten: Ich muss eigentlich nur die Funktion, die den Wert
der Variablen setzt, durchsteppen, damit ein richtiger Wert kommt.
Sorry, ich muss mich noch einmal berichtigen:
Es ist so, dass lediglich die Ausgabe falsch ist, unabhängig davon, ob
ich debugge oder nicht, wenn ich hover oder die Konsole befrage, wird
mir das richtige angezeigt, ausgeben wird das falsche.
Und was ich vielleicht auch noch sagen sollte: Es ist ein Array, welches
ausgeben wird, aber in der falschen Reihenfolge (letztes Element wird
als index=0 und das erste Element als letztes ausgeben)
Ich weiß, ihr wollt mich am liebsten schlagen, für die ganzen
Ergänzungen, aber besser spät als nie oder ;)
Tja ohne Code ist das doch nur Rätselraten. Aber vermutlich wirst du an
anderer Stelle, in einem anderen "Thread" die Variable einfach
überschreiben..?
Ich habe früher mal ... lang ist's her ... JS mit "Aptana Studio"
geschrieben und debuggt. Gibts das noch? Vlt. mal probieren?
Ansonsten mache ich das gelegentlich extrem altmodisch: Ich schreibe
Zwischenwerte oder Ausgaben in Textfelder oder in Dialogboxen, bis es
funzt. Bisher habe ich so noch jeden Fehler gefunden ...
hä schrieb:> Es ist anscheinend wirklich so, dass die Werte zwischendurch nochmal> geändert werden
Falls du es noch nicht so hast, ich empfehle
1
"use strict";
an den Anfang aller JS Dateinen zu schreiben. Dadurch wird dann z.B. bei
Dingen wie "function x(){y=1;}" ein Fehler geworfen, wenn y noch nicht
definiert wurde, statt das still eine Globale Variable angelegt wird.
Schau dir auch noch den Unterschied zwischen var, let und const an. [1]
(Einige sagen, man solle immer let statt var verwenden, aber in einigen
Fällen ist die Semantik von var besser geeignet.). Besonders bei Dingen
wie dem Setzen von Callbacks in Schleifen kann der Scope von Variablen
entscheidend sein. Beispiel:
1
for(vari=0;i<2;i++)
2
setTimeout(()=>alert(i));// gibt beide male 2 aus, weil Ausgabe nach schleifen ende und i immer die selbe Variable im selben Scope, die nach der Schleife auf 2 stand
3
for(leti=0;i<2;i++)// (erinnert sich noch jemand an den Firefox bug, der früher mal let hier wie var behandelte? Stundenlanges Debugging...)
4
setTimeout(()=>alert(i));// gibt 0 und 1 aus, weil Wert von i als neue Variable im Blockscope der Schleife
5
for(vari=0;i<2;i++){// Nochmal das gleiche, aber mit dem expliziten Anlegen von j im Blockscope, statt implizit mit let in der Schleife
6
letj=i;
7
setTimeout(()=>alert(j));
8
}
9
for(vari=0;i<2;i++)
10
(function(){// Befor es let gab musste man das noch so machen, mit einem neuen Function Scope
11
varj=i;
12
setTimeout(()=>alert(j));
13
})();
Globale Variablen sollten in den meisten fällen vermieden werden, oder
zumindest auf ein Modul eingeschränkt.
Arrow Funktionen (lambdas) und anonyme Funktionen und
Function.prototype.bind sind unter anderem praktisch, Parameter von
Funktionen zu ändern oder festzulegen, und dabei je nachdem noch Werte
in Variablen mit anderem Scope zu kopieren. (Aber Achtung, Arrow
Funktionen haben "this" nicht, normale schon). Ist zwar mit den Block
scopes etwas aus der Mode gekommen.
Und dann sind eventuell Promises, async und await für die saubere
Behandlung Asynchroner Abläufe noch praktisch. Eine callback Funktion,
die einmalig aufgerufen wird, und eventuell einen Fehler zurückgeben
könnte, ist immer Fehleranfälliger und unpraktischer als Promises. Bei
async/await muss man aber etwas aufpassen, aufgrund der versteckten
Nebenläufigkeit sind async Funktionen nur die teile quasiatomar, wo kein
await drinsteht. Das heisst sowas ist möglich:
1
letx;
2
setTimeout(()=>{x="überschrieben";},1000);// Nach einer Sekunde, x auf "überschrieben" setzen.
3
4
(async()=>{
5
x="Anfangswert";
6
// Auf irgendwas asynchrones warten, währenddessen können andere Callbacks ausgeführt und damit x geändert werden