Как я могу заставить console.log показывать текущее состояние объекта?

146

В Safari без надстроек (и на самом деле в большинстве других браузеров) console.logобъект будет отображаться в последнем состоянии выполнения, а не в том состоянии, когда он console.logбыл вызван.

Я должен клонировать объект, просто чтобы вывести его через, console.logчтобы получить состояние объекта в этой строке.

Пример:

var test = {a: true}
console.log(test); // {a: false}
test.a = false; 
console.log(test); // {a: false}
Wesley
источник
2
Пример проблемы jsfiddle и различные варианты ее
Лука,
7
Для функции log крайне нелогично выводить прямую ссылку на объект. Это называется часы , которые сильно отличаются от записи в журнале. Это не имеет больше смысла делать это при регистрации объекта, чем при регистрации переменной, хранящей примитивное значение.
faintsignal
2
Как я никогда не сталкивался с этим раньше? Я нахожу это пугающим
ErikAGriffin

Ответы:

172

Я думаю, что вы ищете console.dir().

console.log()не делает то, что вы хотите, потому что он печатает ссылку на объект, и когда вы открываете его, он меняется. console.dirпечатает каталог свойств объекта во время его вызова.

Идея JSON ниже хороша; Вы можете даже проанализировать строку JSON и получить объект для просмотра, например, что даст вам .dir ():

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

Evan
источник
38
Для меня в Chrome13 нет разницы между console.logаconsole.dir
Эндрю Д.
Хм, это удивительно - это работает в Firebug. Я думал, что то же самое в Webkit.
Эван
1
Что я вижу в Chrome, так это то, что если вы откроете консоль после выполнения оператора log, то при развертывании он выполнит ленивую оценку. Но если консоль уже открыта (например, вы открываете консоль, а затем нажимаете «Обновить» на странице), она выполнит тщательную оценку - то есть напечатает значение во время выполнения оператора log.
Polemarch
6
Кроме того, dir относится к JSON, а мелкое копирование - к глубокому копированию. console.dir () будет оценивать только свойства объекта верхнего уровня (другие более глубоко вложенные объекты не будут оцениваться), тогда как JSON будет работать рекурсивно.
Polemarch
9
Аналогично для меня console.dirне работает в Chrome (v33). Вот сравнение решений, которые предложили люди: jsfiddle.net/luken/M6295
Люк
71

Что я обычно делаю, если я хочу видеть его состояние во время регистрации, я просто конвертирую его в строку JSON.

console.log(JSON.stringify(a));
Алекс Турпин
источник
4
Отлично, это был хороший совет для меня: мне просто пришлось снова разобрать его, чтобы мой объект находился прямо в консоли. function odump(o){ console.log($.parseJSON(JSON.stringify(o))); }
Крис
1
спасибо, это работает для меня! console.dir не печатал его
ах-сян хан
1
Что делать, если ваш объект содержит круговую структуру?
Алекс Макмиллан
1
@AlexMcMillan Вы можете использовать одну из нескольких библиотек, которые позволяют JSON-форматирование объектов с циклическими ссылками.
Алекс Турпин
7
Geez. Это должна быть простая, очевидная вещь, которую можно сделать. Вместо этого мы должны преобразовать в строку, проанализировать, зарегистрировать и использовать специальную библиотеку циклических ссылок!?! Я думаю, что браузеры должны лучше выполнять поддержку простых отладочных задач.
Марс
26

Ваниль JS:

@ Эван ответ здесь кажется лучшим. Просто (ab) используйте JSON.parse / stringify, чтобы эффективно сделать копию объекта.

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

JQuery конкретное решение:

Вы можете создать снимок объекта в определенный момент времени с помощью jQuery.extend

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

Здесь на самом деле происходит то, что jQuery создает новый объект с testсодержимым объекта и регистрирует его (так что он не изменится).

AngularJS (1) конкретное решение:

Angular предоставляет copyфункцию, которую можно использовать для того же эффекта:angular.copy

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

Функция обертки Vanilla JS:

Вот функция, которая оборачивает, console.logно сделает копию любых объектов перед выходом их из системы.

Я написал это в ответ на несколько похожих, но менее надежных функций в ответах. Он поддерживает несколько аргументов и не будет пытаться копировать вещи, если они не являются обычными объектами.

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

пример использования :consoleLogWithObjectCopy('obj', {foo: 'bar'}, 1, /abc/, {a: 1})

Зак Лисобей
источник
6

Это > Objectв консоли, не только показывает текущее состояние. Это фактически задерживает чтение объекта и его свойств до тех пор, пока вы его не развернете.

Например,

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

Затем разверните первый вызов, это будет правильно, если вы сделаете это до второго console.logвозврата

Джо
источник
2

используя подсказку Xeon06, вы можете проанализировать его JSON в объекте, и вот функция журнала, которую я сейчас использую для вывода своих объектов:

function odump(o){
   console.log($.parseJSON(JSON.stringify(o)));
}
Крис
источник
1

Я определил утилиту:

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

и когда я хочу войти в консоль, я просто делаю:

MyLog("hello console!");

Это работает очень хорошо!

Мигио Б
источник
1

Существует возможность использовать библиотеку отладчика.

https://debugjs.net/

Просто включите сценарий на свою веб-страницу и поместите в журнал заявления.

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

логирование

var test = {a: true}
log(test); // {a: true}
test.a = false; 
log(test); // {a: false}
Такаши Харано
источник
0

Я могу быть застрелен за то, что предложил это, но это может быть сделано еще на один шаг вперед. Мы можем напрямую расширить консольный объект, чтобы сделать его более понятным.

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

Я не знаю, вызовет ли это какой-то тип столкновения библиотеки / ядерного распада / разрыва в континууме пространства-времени. Но это прекрасно работает в моих тестах qUnit. :)

Дейв
источник
1
Это ничего не регистрирует. Он просто проглатывает результат строкового преобразования чего-либо. Забавно, что его проголосовали
Зак Лисобей
0

Просто обновите страницу после открытия консоли или открытия консоли перед отправкой запроса на целевую страницу ....

А. Кауд
источник
-1

Просто напечатайте весь объект на консоли.

console.dir(object);
Мангеш Бхапкар
источник