¿Cómo puedo hacer que console.log muestre el estado actual de un objeto?

146

En Safari sin complementos (y en realidad la mayoría de los otros navegadores), console.logmostrará el objeto en el último estado de ejecución, no en el estado en el que console.logse llamó.

Tengo que clonar el objeto solo para generarlo y console.logobtener el estado del objeto en esa línea.

Ejemplo:

var test = {a: true}
console.log(test); // {a: false}
test.a = false; 
console.log(test); // {a: false}
Wesley
fuente
2
jsfiddle ejemplo del problema y varias soluciones dadas a continuación: jsfiddle.net/luken/M6295
Lucas
77
Es extremadamente contradictorio que la función de registro genere una referencia en vivo al objeto. Eso se llama un reloj , que es muy diferente a una entrada de registro. No tiene más sentido hacer esto al registrar un objeto que al registrar una variable que almacena un valor primitivo.
faintsignal
2
¿Cómo es que nunca he cruzado esto antes? Me parece aterrador
ErikAGriffin

Respuestas:

172

Creo que lo estás buscando console.dir().

console.log()no hace lo que quiere porque imprime una referencia al objeto, y para cuando lo abre, está cambiado. console.dirimprime un directorio de las propiedades en el objeto en el momento en que lo llama.

La idea de JSON a continuación es buena; incluso podría analizar la cadena JSON y obtener un objeto navegable como lo que .dir () le daría:

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

evan
fuente
38
Para mí en Chrome13 no hay diferencia entre console.logyconsole.dir
Andrew D.
Hm, eso es sorprendente, funciona en Firebug. Pensé que era lo mismo en Webkit.
evan
1
Lo que estoy viendo en Chrome es que si abres la consola después de que se haya ejecutado la declaración de registro, entonces hará una evaluación perezosa cuando la expandas. Pero si la consola ya está abierta (por ejemplo, abre la consola y luego presiona actualizar en la página), realizará una evaluación ansiosa, es decir, imprimirá el valor en el momento en que se ejecutó la instrucción de registro.
Polemarch
66
Además, dir es a JSON como una copia superficial es una copia profunda. console.dir () solo evaluará las propiedades del objeto de nivel superior (no se evaluarían otros objetos más profundamente anidados), mientras que JSON irá de forma recursiva.
Polemarch
9
Del mismo modo para mí console.dirno funciona en Chrome (v33). Aquí hay una comparación de las soluciones que la gente ha ofrecido: jsfiddle.net/luken/M6295
Luke
71

Lo que generalmente hago si quiero ver su estado en el momento en que se registró es simplemente convertirlo a una cadena JSON.

console.log(JSON.stringify(a));
Alex Turpin
fuente
44
Genial, esa fue una buena pista para mí: solo tuve que analizarlo nuevamente para tener mi objeto justo en la consola. function odump(o){ console.log($.parseJSON(JSON.stringify(o))); }
Chris
1
gracias esto funciona para mi! console.dir no lo imprimió
ah-shiang han
1
¿Qué pasa si su objeto contiene una estructura circular?
Alex McMillan
1
@AlexMcMillan Puede usar una de varias bibliotecas que permiten la cadena JSON de objetos con referencias circulares.
Alex Turpin
77
Geez Esto debería ser algo simple y obvio para poder hacer. En su lugar, tenemos que stringificar, analizar, registrar y usar una biblioteca de referencia circular especial. Creo que los navegadores deben hacer un mejor trabajo para admitir necesidades de depuración simples.
Marte
26

Vanilla JS:

La respuesta de @evan parece mejor aquí. Simplemente (ab) use JSON.parse / stringify para hacer efectivamente una copia del objeto.

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

Solución específica de JQuery:

Puede crear una instantánea de un objeto en un momento determinado con jQuery.extend

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

Lo que realmente está sucediendo aquí es que jQuery está creando un nuevo objeto con el testcontenido del objeto y lo está registrando (para que no cambie).

AngularJS (1) solución específica:

Angular proporciona una copyfunción que puede usarse para el mismo efecto:angular.copy

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

Función de envoltura Vanilla JS:

Aquí hay una función que se ajusta console.logpero hará una copia de cualquier objeto antes de cerrar la sesión.

Escribí esto en respuesta a algunas funciones similares pero menos robustas en las respuestas. Admite múltiples argumentos, y no intentará copiar cosas si no son objetos normales .

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

ejemplo de uso :consoleLogWithObjectCopy('obj', {foo: 'bar'}, 1, /abc/, {a: 1})

Zach Lysobey
fuente
6

Eso > Objecten la consola, no solo muestra el estado actual. En realidad, está aplazando la lectura del objeto y sus propiedades hasta que lo expanda.

Por ejemplo,

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

Luego expanda la primera llamada, será correcta, si lo hace antes de que console.logregrese la segunda

Joe
fuente
2

usando la sugerencia de Xeon06, puede analizar su JSON en un objeto, y aquí está la función de registro que ahora uso para volcar mis objetos:

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

Definí una utilidad:

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

y cuando quiero iniciar sesión en la consola simplemente hago:

MyLog("hello console!");

¡Funciona muy bien!

Migio B
fuente
1

Hay una opción para usar una biblioteca de depurador.

https://debugjs.net/

Simplemente incluya el script en su página web y coloque declaraciones de registro.

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

Inicio sesión

var test = {a: true}
log(test); // {a: true}
test.a = false; 
log(test); // {a: false}
Takashi Harano
fuente
0

Me pueden disparar por sugerir esto, pero esto puede llevarse un paso más allá. Podemos extender directamente el objeto de la consola para que quede más claro.

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

No sé si esto causará algún tipo de colisión de biblioteca / fusión nuclear / rasgadura en el continuo espacio-tiempo. Pero funciona muy bien en mis pruebas qUnit. :)

Dave
fuente
1
Esto no registra nada. Simplemente se traga el resultado de encadenar algo. Es curioso que haya recibido votos positivos
Zach Lysobey
0

Simplemente actualice la página después de abrir la consola o abra la consola antes de enviar la solicitud a la página de destino ...

A. Qaoud
fuente
-1

Simplemente imprima todo el objeto en la consola.

console.dir(object);
Mangesh Bhapkar
fuente