Wie kann ich console.log dazu bringen, den aktuellen Status eines Objekts anzuzeigen?


146

In Safari ohne Add-Ons (und in den meisten anderen Browsern) console.logwird das Objekt im letzten Ausführungsstatus angezeigt, nicht im Status, in dem console.loges aufgerufen wurde.

Ich muss das Objekt klonen, nur um es über auszugeben console.log, um den Status des Objekts in dieser Zeile zu erhalten.

Beispiel:

var test = {a: true}
console.log(test); // {a: false}
test.a = false; 
console.log(test); // {a: false}

2
jsfiddle Beispiel für das Problem und verschiedene Lösungen unten angegeben: jsfiddle.net/luken/M6295
Luke

7
Es ist äußerst uninteressant für die Protokollfunktion , eine Live-Referenz auf das Objekt auszugeben. Das nennt man eine Uhr , die sich stark von einem Protokolleintrag unterscheidet. Dies ist beim Protokollieren eines Objekts nicht sinnvoller als beim Protokollieren einer Variablen, in der ein primitiver Wert gespeichert ist.
Ohnmachtssignal

2
Wie habe ich noch nie etwas davon gesehen? Ich finde das erschreckend
ErikAGriffin

Antworten:


171

Ich denke du suchst console.dir().

console.log()macht nicht das, was Sie wollen, weil es einen Verweis auf das Objekt druckt und es sich ändert, wenn Sie es öffnen. console.dirdruckt ein Verzeichnis der Eigenschaften im Objekt zum Zeitpunkt des Aufrufs.

Die folgende JSON-Idee ist gut. Sie könnten sogar die JSON-Zeichenfolge analysieren und ein durchsuchbares Objekt erhalten, wie es Ihnen .dir () geben würde:

console.log(JSON.parse(JSON.stringify(obj)));


38
Für mich in Chrome13 kein Unterschied zwischen console.logundconsole.dir
Andrew D.

Hm, das ist überraschend - es funktioniert in Firebug. Ich hatte gedacht, dass es im Webkit genauso ist.
Evan

1
Was ich in Chrome sehe, ist, dass wenn Sie die Konsole öffnen, nachdem die Protokollanweisung ausgeführt wurde, sie beim Erweitern die verzögerte Auswertung durchführt. Wenn die Konsole jedoch bereits geöffnet ist (z. B. wenn Sie die Konsole öffnen und dann auf der Seite auf Aktualisieren klicken), wird eine eifrige Auswertung durchgeführt, dh der Wert wird zum Zeitpunkt der Ausführung der Protokollanweisung gedruckt.
Polemarch

6
Außerdem ist dir zu JSON wie Flachkopie zu Tiefkopie. console.dir () wertet nur die Eigenschaften des Objekts der obersten Ebene aus (andere tiefer verschachtelte Objekte würden nicht ausgewertet), während JSON rekursiv ausgeführt wird.
Polemarch

9
Ebenso console.dirfunktioniert bei mir nicht in Chrome (v33). Hier ist ein Vergleich der Lösungen, die Menschen angeboten haben: jsfiddle.net/luken/M6295
Luke

71

Wenn ich den Status zum Zeitpunkt der Protokollierung anzeigen möchte, konvertiere ich ihn einfach in eine JSON-Zeichenfolge.

console.log(JSON.stringify(a));

4
Großartig, das war ein schöner Hinweis für mich: Ich musste es nur noch einmal analysieren, um mein Objekt direkt in der Konsole zu haben. function odump(o){ console.log($.parseJSON(JSON.stringify(o))); }
Chris

1
danke das funktioniert bei mir! console.dir hat es nicht gedruckt
ah-shiang han

1
Was ist, wenn Ihr Objekt eine kreisförmige Struktur enthält?
Alex McMillan

1
@AlexMcMillan Sie können eine von mehreren Bibliotheken verwenden, die die JSON-Stringifizierung von Objekten mit Zirkelverweisen ermöglichen.
Alex Turpin

7
Meine Güte. Dies sollte eine einfache, offensichtliche Sache sein, die man tun kann. Stattdessen müssen wir eine spezielle Zirkelreferenzbibliothek stringifizieren, analysieren, protokollieren und verwenden!?! Ich denke, die Browser müssen die einfachen Debugging-Anforderungen besser unterstützen.
Mars

26

Vanilla JS:

@ evans Antwort scheint hier am besten zu sein. Verwenden Sie einfach (ab) JSON.parse / stringify, um effektiv eine Kopie des Objekts zu erstellen.

console.log(JSON.parse(JSON.stringify(test)));

JQuery-spezifische Lösung:

Mit können Sie zu einem bestimmten Zeitpunkt einen Schnappschuss eines Objekts erstellen jQuery.extend

console.log($.extend({}, test));

Was hier tatsächlich passiert, ist, dass jQuery mit dem ein neues Objekt erstellt test Inhalt Objekts erstellt und dieses protokolliert (damit es sich nicht ändert).

AngularJS (1) spezifische Lösung:

Angular bietet eine copyFunktion, die mit demselben Effekt verwendet werden kann:angular.copy

console.log(angular.copy(test));

Vanilla JS-Wrapper-Funktion:

Hier ist eine Funktion, die umschließt, console.logaber eine Kopie aller Objekte erstellt, bevor sie abgemeldet werden.

Ich habe dies als Antwort auf einige ähnliche, aber weniger robuste Funktionen in den Antworten geschrieben. Es unterstützt mehrere Argumente und versucht nicht , Dinge zu kopieren, wenn es sich nicht um reguläre Objekte handelt.

function consoleLogWithObjectCopy () {
  var args = [].slice.call(arguments);
  var argsWithObjectCopies = args.map(copyIfRegularObject)
  return console.log.apply(console, argsWithObjectCopies)
}

function copyIfRegularObject (o) {
  const isRegularObject = typeof o === 'object' && !(o instanceof RegExp)
  return isRegularObject ? copyObject(o) : o
}

function copyObject (o) {
  return JSON.parse(JSON.stringify(o))
}

Anwendungsbeispiel :consoleLogWithObjectCopy('obj', {foo: 'bar'}, 1, /abc/, {a: 1})


6

Das > Object in der Konsole zeigt nicht nur den aktuellen Status. Das Lesen des Objekts und seiner Eigenschaften wird verschoben, bis Sie es erweitern.

Beispielsweise,

var test = {a: true}
console.log(test);
setTimeout(function () {
    test.a = false; 
    console.log(test);
}, 4000);

Erweitern Sie dann den ersten Aufruf, es ist richtig, wenn Sie es tun, bevor der zweite console.logzurückkehrt


2

Mit dem Hinweis von Xeon06 können Sie seinen JSON in einem Objekt analysieren. Hier ist die Protokollfunktion, mit der ich jetzt meine Objekte entleere:

function odump(o){
   console.log($.parseJSON(JSON.stringify(o)));
}

1

Ich habe ein Dienstprogramm definiert:

function MyLog(text) {
    console.log(JSON.stringify(text));
}

und wenn ich mich an der Konsole anmelden möchte, mache ich einfach:

MyLog("hello console!");

Es funktioniert sehr gut!



1

Es besteht die Möglichkeit, eine Debugger-Bibliothek zu verwenden.

https://debugjs.net/

Fügen Sie das Skript einfach in Ihre Webseite ein und fügen Sie Protokollanweisungen ein.

<script src="debug.js"></script>

Protokollierung

var test = {a: true}
log(test); // {a: true}
test.a = false; 
log(test); // {a: false}

0

Ich werde vielleicht erschossen, weil ich das vorgeschlagen habe, aber das kann noch einen Schritt weiter gehen. Wir können das Konsolenobjekt selbst direkt erweitern, um es klarer zu machen.

console.logObject = function(o) {
  (JSON.stringify(o));
}

Ich weiß nicht, ob dies zu einer Art Bibliothekskollision / Kernschmelze / Riss im Raumzeitkontinuum führen wird. Aber es funktioniert wunderbar in meinen qUnit-Tests. :) :)


1
Dies protokolliert nichts. Es schluckt nur das Ergebnis der Stringifizierung. Komisch, dass es positive
Stimmen

0

Aktualisieren Sie einfach die Seite, nachdem Sie die Konsole geöffnet haben, oder öffnen Sie die Konsole, bevor Sie die Anforderung an die Zielseite senden.


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.