Como posso fazer o console.log mostrar o estado atual de um objeto?


146

No Safari sem complementos (e na maioria dos outros navegadores), console.logo objeto será mostrado no último estado de execução, não no estado em que console.logfoi chamado.

Eu tenho que clonar o objeto apenas para produzi-lo via console.logpara obter o estado do objeto nessa linha.

Exemplo:

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

2
Exemplo do problema jsfiddle e várias soluções dadas abaixo: jsfiddle.net/luken/M6295
Luke

7
É extremamente contra-intuitivo para a função log gerar uma referência ao vivo para o objeto. Isso é chamado de relógio , que é muito diferente de uma entrada de log. Não faz mais sentido fazer isso ao registrar um objeto do que faria ao registrar uma variável que armazena um valor primitivo.
faintsignal

2
Como nunca passei por isso antes? Acho isso assustador
ErikAGriffin

Respostas:


171

Eu acho que você está procurando console.dir().

console.log()não faz o que você deseja, porque imprime uma referência ao objeto e, quando você o abre, ele é alterado. console.dirimprime um diretório das propriedades no objeto no momento em que você o chama.

A idéia do JSON abaixo é boa; você pode até analisar a string JSON e obter um objeto navegável como o que .dir () daria a você:

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


38
Para mim no Chrome13 não há diferença entre console.logeconsole.dir
Andrew D.

Hum, isso é surpreendente - funciona no Firebug. Eu pensei que era o mesmo no Webkit.
evan

1
O que estou vendo no Chrome é que, se você abrir o console depois que a instrução de log for executada, ela fará uma avaliação lenta quando expandida. Mas se o console já estiver aberto (por exemplo, você abrir o console e clicar em atualizar na página), será feita uma avaliação ágil - por exemplo, imprima o valor no momento em que a instrução de log foi executada.
Polemarch 14/01

6
Além disso, dir é para JSON, como cópia superficial é para cópia profunda. console.dir () avaliará apenas as propriedades do objeto de nível superior (outros objetos aninhados mais profundamente não serão avaliados), enquanto o JSON irá recursivamente.
Polemarch 14/01

9
Da mesma forma, para mim console.dir, não funciona no Chrome (v33). Aqui está uma comparação das soluções que as pessoas ofereceram: jsfiddle.net/luken/M6295
Luke

71

O que eu costumo fazer se quiser ver seu estado no momento em que foi registrado é apenas convertido para uma string JSON.

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

4
Ótimo, essa foi uma boa dica para mim: eu apenas tive que analisá-la novamente para ter meu objeto no console. function odump(o){ console.log($.parseJSON(JSON.stringify(o))); }
31413 Chris

1
obrigado isso funciona para mim! console.dir não imprimi-lo
ah-shiang han

1
e se o seu objeto contiver uma estrutura circular?
Alex McMillan

1
@AlexMcMillan Você pode usar uma das várias bibliotecas que permitem a stringification JSON de objetos com referências circulares.
Alex Turpin #

7
Nossa. Isso deve ser uma coisa simples e óbvia para poder fazer. Em vez disso, temos que restringir, analisar, registrar e usar uma biblioteca de referência circular especial!?! Eu acho que os navegadores precisam fazer um trabalho melhor de suporte a necessidades simples de depuração.
Mars

26

JS de baunilha:

A resposta de @ evan parece melhor aqui. Basta (ab) usar JSON.parse / stringify para efetivamente fazer uma cópia do objeto.

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

Solução específica JQuery:

Você pode criar um instantâneo de um objeto em um determinado momento com jQuery.extend

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

O que realmente está acontecendo aqui é que o jQuery está criando um novo objeto com o testconteúdo do objeto e registrando-o (para que não mude).

Solução específica AngularJS (1):

Angular fornece uma copyfunção que pode ser usada para o mesmo efeito:angular.copy

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

Função de wrapper Vanilla JS:

Aqui está uma função que envolve console.logmas faz uma cópia de qualquer objeto antes de desconectá-lo.

Escrevi isso em resposta a algumas funções semelhantes, mas menos robustas, nas respostas. Ele suporta vários argumentos e não tentará copiar as coisas se elas não forem objetos regulares .

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

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


6

Isso > Objectno console não mostra apenas o estado atual. Na verdade, adiar a leitura do objeto e suas propriedades até você expandi-lo.

Por exemplo,

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

Em seguida, expanda a primeira chamada, ela estará correta, se você fizer antes do console.logretorno da segunda


2

usando a dica do Xeon06, você pode analisar seu JSON em um objeto, e aqui está a função de log que agora uso para despejar meus objetos:

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

1

Eu defini um utilitário:

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

e quando quero fazer logon no console, simplesmente faço:

MyLog("hello console!");

Funciona muito bem!



1

Há uma opção para usar uma biblioteca de depurador.

https://debugjs.net/

Basta incluir o script em sua página da web e colocar instruções de log.

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

Exploração madeireira

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

0

Posso me dar um tiro por sugerir isso, mas isso pode ser dado um passo adiante. Podemos estender diretamente o próprio objeto do console para torná-lo mais claro.

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

Não sei se isso causará algum tipo de colisão de biblioteca / colapso / ruptura nuclear no continuum do espaço-tempo. Mas funciona lindamente nos meus testes qUnit. :)


1
Isso não registra nada. Apenas engole o resultado de restringir algo. Engraçado que seus upvotes obtidos
Zach Lysobey

0

Simplesmente atualize a página depois de abrir o console ou abra o console antes de enviar a solicitação para a página de destino ....


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.