Ich werde mit dem Code beginnen:
var s = ["hi"];
console.log(s);
s[0] = "bye";
console.log(s);
Einfach, richtig? Als Antwort darauf sagt Firebug:
["hi"]
["bye"]
Wunderbar, aber die JavaScript-Konsole von Chrome (7.0.517.41 Beta) sagt:
["bye"]
["bye"]
Habe ich etwas falsch gemacht oder ist die JavaScript-Konsole von Chrome bei der Bewertung meines Arrays außergewöhnlich faul?
javascript
arrays
logging
google-chrome
console
Eric Mickelsen
quelle
quelle
Antworten:
Danke für den Kommentar, tec. Ich konnte einen vorhandenen unbestätigten Webkit-Fehler finden, der dieses Problem erklärt: https://bugs.webkit.org/show_bug.cgi?id=35801 (BEARBEITEN: jetzt behoben!)
Es scheint eine Debatte darüber zu geben, wie groß der Fehler ist und ob er behoben werden kann. Es scheint mir ein schlechtes Benehmen zu sein. Es hat mich besonders beunruhigt, weil es zumindest in Chrome auftritt, wenn sich der Code in Skripten befindet, die unmittelbar (vor dem Laden der Seite) ausgeführt werden, selbst wenn die Konsole geöffnet ist, wenn die Seite aktualisiert wird. Das Aufrufen von console.log, wenn die Konsole noch nicht aktiv ist, führt nur zu einem Verweis auf das Objekt in der Warteschlange, nicht auf die Ausgabe, die die Konsole enthält. Daher wird das Array (oder ein beliebiges Objekt) erst ausgewertet, wenn die Konsole bereit ist. Es ist wirklich ein Fall von fauler Bewertung.
Es gibt jedoch eine einfache Möglichkeit, dies in Ihrem Code zu vermeiden:
Durch Aufrufen von toString erstellen Sie eine Darstellung im Speicher, die nicht durch folgende Anweisungen geändert wird, die die Konsole liest, wenn sie bereit ist. Die Konsolenausgabe unterscheidet sich geringfügig von der direkten Übergabe des Objekts, scheint jedoch akzeptabel zu sein:
quelle
Nach Erics Erklärung liegt es daran, dass es sich in
console.log()
der Warteschlange befindet und einen späteren Wert des Arrays (oder Objekts) druckt.Es kann 5 Lösungen geben:
quelle
Sie können ein Array klonen mit
Array#slice
:Eine Funktion, die Sie stattdessen verwenden können
console.log
, hat dieses Problem nicht:Für Objekte scheint die beste Methode leider darin zu bestehen, zuerst mit einem Nicht-WebKit-Browser zu debuggen oder eine komplizierte Funktion zum Klonen zu schreiben. Wenn Sie nur mit einfachen Objekten arbeiten, bei denen die Reihenfolge der Tasten keine Rolle spielt und keine Funktionen vorhanden sind, können Sie immer Folgendes tun:
Alle diese Methoden sind offensichtlich sehr langsam. Noch mehr als bei normalen
console.log
s müssen Sie sie nach dem Debuggen entfernen.quelle
Dies wurde in Webkit gepatcht. Wenn Sie jedoch das React-Framework verwenden, geschieht dies unter bestimmten Umständen für mich, wenn Sie solche Probleme haben, verwenden Sie sie einfach so, wie andere vorschlagen:
quelle
JSON.parse(JSON.stringify(event))
bekommt nicht die richtige Tiefe / Genauigkeit. Debugger-Anweisungen sind die einzige echte Lösung, die ich gefunden habe, um den richtigen Einblick zu erhalten.Dies ist bereits beantwortet, aber ich werde meine Antwort trotzdem fallen lassen. Ich habe einen einfachen Konsolen-Wrapper implementiert, der unter diesem Problem nicht leidet. Benötigt jQuery.
Es werden nur Methoden implementiert
log
,warn
underror
Sie müssen weitere hinzufügen, damit es mit einem regulären austauschbar istconsole
.quelle
Es sieht so aus, als würde Chrome in seiner "Pre Compile" -Phase jede Instanz von "s" durch einen Zeiger auf das tatsächliche Array ersetzen .
Eine Möglichkeit besteht darin, das Array zu klonen und stattdessen eine neue Kopie zu protokollieren:
quelle
Die bisher kürzeste Lösung besteht darin, die Array- oder Objektverbreitungssyntax zu verwenden, um einen Klon von Werten zu erhalten, die zum Zeitpunkt der Protokollierung beibehalten werden sollen, dh:
Seien Sie jedoch gewarnt, da es sich um eine flache Kopie handelt, sodass tief verschachtelte nicht-primitive Werte nicht geklont und somit in ihrem geänderten Zustand in der Konsole angezeigt werden
quelle