Comment puis-je faire en sorte que console.log affiche l'état actuel d'un objet?


146

Dans Safari sans add-on (et en fait la plupart des autres navigateurs), console.logaffichera l'objet au dernier état d'exécution, pas à l'état où il a console.logété appelé.

Je dois cloner l'objet juste pour le sortir via console.logpour obtenir l'état de l'objet à cette ligne.

Exemple:

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

2
jsfiddle exemple du problème et diverses solutions donnés ci-dessous: jsfiddle.net/luken/M6295
Luc

7
Il est extrêmement contre-intuitif pour la fonction de journalisation de générer une référence en direct à l'objet. Cela s'appelle une montre , ce qui est très différent d'une entrée de journal. Cela n'a pas plus de sens de faire cela lors de la journalisation d'un objet que lors de la journalisation d'une variable stockant une valeur primitive.
faintsignal

2
Comment n'en ai-je jamais fait auparavant? Je trouve cela effrayant
ErikAGriffin

Réponses:


172

Je pense que vous cherchez console.dir().

console.log()ne fait pas ce que vous voulez car il imprime une référence à l'objet, et au moment où vous l'ouvrez, il est changé. console.dirimprime un répertoire des propriétés de l'objet au moment où vous l'appelez.

L'idée JSON ci-dessous est bonne; vous pouvez même analyser la chaîne JSON et obtenir un objet navigable comme ce que .dir () vous donnerait:

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


38
Pour moi dans Chrome13 aucune différence entre console.logetconsole.dir
Andrew D.

Hm, c'est surprenant - cela fonctionne dans Firebug. J'avais pensé que c'était la même chose dans Webkit.
evan le

1
Ce que je vois dans Chrome, c'est que si vous ouvrez la console après l'exécution de l'instruction de journal, elle effectuera l'évaluation paresseuse lorsque vous la développerez. Mais si la console est déjà ouverte (par exemple, vous ouvrez la console puis appuyez sur Actualiser sur la page), elle effectuera une évaluation impatiente - c'est-à-dire afficher la valeur au moment où l'instruction de journal a été exécutée.
Polemarch

6
En outre, dir est vers JSON, comme la copie peu profonde est vers la copie profonde. console.dir () n'évaluera que les propriétés de l'objet de niveau supérieur (d'autres objets plus profondément imbriqués ne seront pas évalués), alors que JSON ira de manière récursive.
Polémarque

9
De même pour moi console.dirne fonctionne pas dans Chrome (v33). Voici une comparaison des solutions que les gens ont proposées: jsfiddle.net/luken/M6295
Luke

71

Ce que je fais habituellement si je veux voir son état au moment où il a été enregistré, c'est que je le convertis simplement en une chaîne JSON.

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

4
Génial, c'était un bon indice pour moi: je devais juste l'analyser à nouveau pour avoir mon objet directement dans la console. function odump(o){ console.log($.parseJSON(JSON.stringify(o))); }
Chris

1
merci cela fonctionne pour moi! console.dir ne l'a pas imprimé
ah-shiang han

1
et si votre objet contenait une structure circulaire?
Alex McMillan

1
@AlexMcMillan Vous pouvez utiliser l' une des nombreuses bibliothèques qui permettent la stringification JSON des objets avec des références circulaires.
Alex Turpin du

7
Bon sang. Cela devrait être une chose simple et évidente à faire. Au lieu de cela, nous devons stringifier, analyser, enregistrer et utiliser une bibliothèque de référence circulaire spéciale!?! Je pense que les navigateurs doivent mieux répondre aux besoins de débogage simples.
Mars

26

Vanille JS:

La réponse de @ evan semble la meilleure ici. Il suffit (ab) d'utiliser JSON.parse / stringify pour créer efficacement une copie de l'objet.

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

Solution spécifique à JQuery:

Vous pouvez créer un instantané d'un objet à un moment donné avec jQuery.extend

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

Ce qui se passe réellement ici, c'est que jQuery crée un nouvel objet avec le test contenu de objet et enregistre cela (pour qu'il ne change pas).

Solution spécifique AngularJS (1):

Angular fournit une copyfonction qui peut être utilisée pour le même effet:angular.copy

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

Fonction wrapper Vanilla JS:

Voici une fonction qui encapsule console.logmais fera une copie de tous les objets avant de les déconnecter.

J'ai écrit ceci en réponse à quelques fonctions similaires mais moins robustes dans les réponses. Il prend en charge plusieurs arguments et n'essaiera pas de copier des choses si ce ne sont pas des objets normaux .

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

exemple d'utilisation :consoleLogWithObjectCopy('obj', {foo: 'bar'}, 1, /abc/, {a: 1})


6

Cette > Object dans la console, ne montre pas seulement l'état actuel. Il diffère en fait la lecture de l'objet et de ses propriétés jusqu'à ce que vous les développiez.

Par exemple,

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

Puis développez le premier appel, ce sera correct, si vous le faites avant le console.logretour du second


2

en utilisant l'indication de Xeon06, vous pouvez analyser son JSON dans un objet, et voici la fonction de journalisation que j'utilise maintenant pour vider mes objets:

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

1

J'ai défini un utilitaire:

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

et quand je veux me connecter à la console, je fais simplement:

MyLog("hello console!");

Il fonctionne très bien!



1

Il existe une option pour utiliser une bibliothèque de débogage.

https://debugjs.net/

Incluez simplement le script dans votre page Web et mettez des instructions de journal.

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

Enregistrement

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

0

Je peux être abattu pour avoir suggéré cela, mais cela peut aller plus loin. Nous pouvons directement étendre l'objet console lui-même pour le rendre plus clair.

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

Je ne sais pas si cela provoquera un certain type de collision de bibliothèque / fusion nucléaire / déchirure dans le continuum de l'espace-temps. Mais cela fonctionne à merveille dans mes tests qUnit. :)


1
Cela n'enregistre rien. Il avale juste le résultat de la stringification de quelque chose. Drôle que ses votes positifs
Zach Lysobey

0

Actualisez simplement la page après avoir ouvert la console ou ouvrez la console avant de soumettre la demande à la page ciblée ...


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.