Come posso fare in modo che console.log mostri lo stato corrente di un oggetto?


146

In Safari senza componenti aggiuntivi (e in realtà la maggior parte degli altri browser), console.logmostrerà l'oggetto all'ultimo stato di esecuzione, non allo stato in cui è console.logstato chiamato.

Devo clonare l'oggetto solo per emetterlo via console.logper ottenere lo stato dell'oggetto su quella linea.

Esempio:

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

2
Esempio jsfiddle del problema e varie soluzioni fornite di seguito: jsfiddle.net/luken/M6295
Luca

7
È estremamente controintuitivo che la funzione log emetta un riferimento attivo all'oggetto. Questo si chiama un orologio , che è molto diverso da una voce di registro. Non ha più senso farlo quando si registra un oggetto di quanto farebbe quando si registra una variabile che memorizza un valore di base.
faintsignal

2
Come mai non ne ho mai visto prima? Lo trovo spaventoso
ErikAGriffin,

Risposte:


172

Penso che tu stia cercando console.dir().

console.log()non fa quello che vuoi perché stampa un riferimento all'oggetto e quando lo apri, è cambiato. console.dirstampa una directory delle proprietà nell'oggetto nel momento in cui viene chiamato.

L'idea JSON qui sotto è buona; potresti anche continuare ad analizzare la stringa JSON e ottenere un oggetto navigabile come quello che ti darebbe .dir ():

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


38
Per me in Chrome13 nessuna differenza tra console.logeconsole.dir
Andrew D.

Hm, è sorprendente, funziona in Firebug. Pensavo fosse lo stesso in Webkit.
evan,

1
Quello che vedo in Chrome è che se apri la console dopo che è stata eseguita l'istruzione di registro, eseguirà la valutazione pigra quando la espandi. Ma se la console è già aperta (ad es. Si apre la console e quindi si preme aggiorna sulla pagina), effettuerà una valutazione entusiasta, ovvero stampa il valore al momento dell'esecuzione dell'istruzione di registro.
Polemarch,

6
Inoltre, dir è su JSON come copia superficiale è copia profonda. console.dir () valuterà solo le proprietà dell'oggetto di livello superiore (altri oggetti più nidificati non verrebbero valutati), mentre JSON andrà in modo ricorsivo.
Polemarch,

9
Allo stesso modo per me console.dirnon funziona in Chrome (v33). Ecco un confronto delle soluzioni che le persone hanno offerto: jsfiddle.net/luken/M6295
Luca

71

Quello che faccio di solito se voglio vedere il suo stato al momento in cui è stato registrato è semplicemente convertirlo in una stringa JSON.

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

4
Fantastico, è stato un bel suggerimento per me: ho dovuto solo analizzarlo di nuovo per avere il mio oggetto direttamente nella console. function odump(o){ console.log($.parseJSON(JSON.stringify(o))); }
Chris

1
grazie questo funziona per me! console.dir non lo ha stampato
ah-shiang han

1
cosa succede se il tuo oggetto contiene una struttura circolare?
Alex McMillan,

1
@AlexMcMillan È possibile utilizzare una delle numerose librerie che consentono la stringificazione JSON di oggetti con riferimenti circolari.
Alex Turpin,

7
Accidenti. Questa dovrebbe essere una cosa semplice e ovvia per essere in grado di fare. Invece dobbiamo stringere, analizzare, registrare e usare una libreria di riferimento circolare speciale!?! Penso che i browser debbano fare un lavoro migliore nel supportare semplici esigenze di debug.
Marte

26

Vanilla JS:

La risposta di @ evan sembra la migliore qui. Basta (ab) usare JSON.parse / stringify per creare in modo efficace una copia dell'oggetto.

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

Soluzione specifica di JQuery:

È possibile creare un'istantanea di un oggetto in un determinato momento con jQuery.extend

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

Ciò che sta realmente accadendo qui è che jQuery sta creando un nuovo oggetto con il testcontenuto dell'oggetto e registrandolo (quindi non cambierà).

Soluzione specifica AngularJS (1):

Angular fornisce una copyfunzione che può essere utilizzata per lo stesso effetto:angular.copy

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

Funzione wrapper Vanilla JS:

Ecco una funzione che avvolge console.logma farà una copia di tutti gli oggetti prima di disconnetterli.

Ho scritto questo in risposta ad alcune funzioni simili ma meno robuste nelle risposte. Supporta più argomenti e non proverà a copiare cose se non sono oggetti regolari .

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))
}

esempio di utilizzo :consoleLogWithObjectCopy('obj', {foo: 'bar'}, 1, /abc/, {a: 1})


6

Quello > Objectnella console non mostra solo lo stato corrente. In realtà è rinviare la lettura dell'oggetto e le sue proprietà fino a quando non lo si espande.

Per esempio,

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

Quindi espandi la prima chiamata, sarà corretta, se lo fai prima che console.logritorni la seconda


2

usando il suggerimento di Xeon06, puoi analizzare il suo JSON in un oggetto, ed ecco la funzione di log che ora uso per scaricare i miei oggetti:

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

1

Ho definito un'utilità:

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

e quando voglio accedere alla console, faccio semplicemente:

MyLog("hello console!");

Funziona molto bene!



1

C'è un'opzione per usare una libreria di debugger.

https://debugjs.net/

Basta includere lo script nella tua pagina web e inserire le dichiarazioni del registro.

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

Registrazione

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

0

Potrei essere colpito per aver suggerito questo, ma questo può essere fatto un passo avanti. Possiamo estendere direttamente l'oggetto console stesso per renderlo più chiaro.

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

Non so se questo causerà qualche tipo di collisione della biblioteca / fusione nucleare / strappo nel continuum spazio-temporale. Ma funziona magnificamente nei miei test qUnit. :)


1
Questo non registra nulla. Ingoia semplicemente il risultato di stringere qualcosa. Divertente che abbia ottenuto voti
Zach Lysobey il

0

Basta aggiornare la pagina dopo aver aperto la console o aprire la console prima di inviare la richiesta alla pagina di destinazione ....


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.