如何让 console.log 显示对象的当前状态?

Posted

技术标签:

【中文标题】如何让 console.log 显示对象的当前状态?【英文标题】:How can I make console.log show the current state of an object? 【发布时间】:2011-11-15 09:17:40 【问题描述】:

在没有附加组件的 Safari(实际上是大多数其他浏览器)中,console.log 将显示对象的最后执行状态,而不是调用 console.log 时的状态。

我必须克隆对象只是为了通过console.log 输出它以获取该行的对象状态。

示例:

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

【问题讨论】:

jsfiddle 问题示例和下面给出的各种解决方案:jsfiddle.net/luken/M6295 log 函数输出对对象的实时引用是非常违反直觉的。这称为watch,它与日志条目有很大不同。记录对象时这样做比记录存储原始值的变量时更有意义。 我以前怎么从来没有接触过这个?我觉得这很可怕 【参考方案1】:

只需在控制台上打印整个对象。

console.log(object);

【讨论】:

这显示对象在当前时间的状态,而不是在记录时。 请在您的答案中添加一些解释,以便其他人可以从中学习。如果console.log() 打印出意外的输出,您的回答如何帮助解决这个问题?【参考方案2】:

原版JS:

@evan's answer 似乎在这里最好。只需(ab)使用 JSON.parse/stringify 来有效地制作对象的副本。

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

JQuery具体解决方案:

您可以使用jQuery.extend在某个时间点创建对象的快照

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

这里实际发生的是 jQuery 正在使用 test 对象的内容创建一个新对象,并将其记录下来(因此它不会改变)。

AngularJS(一)具体解决方案:

Angular 提供了一个copy 函数,可以用来达到同样的效果:angular.copy

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

Vanilla JS 封装函数:

这是一个包装 console.log 的函数,但会在注销之前复制任何对象。

我写这个是为了回应答案中一些类似但不太健壮的功能。它支持多个参数,并且如果它们不是 常规 对象,则 not 会尝试复制它们。

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)

【讨论】:

【参考方案3】:

有一个使用调试器库的选项。

https://debugjs.net/

只需将脚本包含到您的网页中并放入日志语句即可。

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

记录

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

【讨论】:

【参考方案4】:

打开控制台后只需刷新页面,或者在向目标页面提交请求之前打开控制台......

【讨论】:

请在您的答案中添加一些解释,以便其他人可以从中学习【参考方案5】:

您可能希望以人类可读的方式记录对象:

console.log(JSON.stringify(myObject, null, 2));

这会使对象在每个级别缩进 2 个空格。

How can I pretty-print JSON using javascript?

【讨论】:

【参考方案6】:

我可能会因为提出这个建议而被枪杀,但这可以更进一步。我们可以直接扩展控制台对象本身,让它更清晰。

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

我不知道这是否会在时空连续体中导致某种类型的图书馆碰撞/核熔毁/撕裂。但它在我的 qUnit 测试中运行良好。 :)

【讨论】:

这不会记录任何内容。它只是吞噬了对某些东西进行字符串化的结果。有趣的是它得到了赞成 请在您的答案中添加一些解释,以便其他人可以从中学习【参考方案7】:

我定义了一个实用程序:

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

当我想登录控制台时,我只需这样做:

MyLog("hello console!");

效果很好!

【讨论】:

【参考方案8】:

我想你正在寻找console.dir()

console.log() 不会做你想做的事,因为它会打印对对象的引用,当你打开它时,它已经改变了。 console.dir 在您调用它时打印对象中的属性目录。

下面的 JSON 思路不错;你甚至可以继续解析 JSON 字符串并获得一个可浏览的对象,就像 .dir() 给你的那样:

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

【讨论】:

对我来说在 Chrome13 中 console.logconsole.dir 之间没有区别 嗯,这很令人惊讶——它可以在 Firebug 中使用。我原以为在 Webkit 中也是如此。 我在 Chrome 中看到的是,如果您在日志语句运行后打开控制台,那么当您展开它时它会进行惰性评估。但是如果控制台已经打开(例如,您打开控制台然后点击页面上的刷新),它会进行急切评估 - 即在运行日志语句时打印值。 另外,dir 是 JSON 就像浅拷贝是深拷贝一样。 console.dir() 只会评估***对象的属性(不会评估其他嵌套更深的对象),而 JSON 会递归。 同样对我来说console.dir 在 Chrome (v33) 中不起作用。以下是人们提供的解决方案的比较:jsfiddle.net/luken/M6295【参考方案9】:

使用 Xeon06 的提示,您可以在对象中解析他的 JSON,这是我现在用来转储对象的日志函数:

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

【讨论】:

【参考方案10】:

如果我想查看它在记录时的状态,我通常会做的就是将其转换为 JSON 字符串。

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

【讨论】:

太好了,这对我来说是一个很好的提示:我只需要再次解析它就可以将我的对象放在控制台中。 function odump(o) console.log($.parseJSON(JSON.stringify(o))); 感谢这对我有用! console.dir 没有打印出来 如果您的对象恰好包含圆形结构怎么办? @AlexMcMillan 您可以使用 one of several 库,这些库允许使用循环引用对对象进行 JSON 字符串化。 天啊。这应该是一件简单、显而易见的事情。相反,我们必须字符串化、解析、记录和使用特殊的循环引用库!?!我认为浏览器需要更好地支持简单的调试需求。【参考方案11】:

控制台中的&gt; Object 不仅显示当前状态。它实际上是推迟读取对象及其属性,直到您展开它。

例如,

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

然后展开第一个调用就正确了,如果你在第二个console.log返回之前做的话

【讨论】:

以上是关于如何让 console.log 显示对象的当前状态?的主要内容,如果未能解决你的问题,请参考以下文章

console.log 如何打印对象

JS 获取当前浏览器宽高

八个console命令,让js调试更简单

九个Console命令,让js调试更简单

console.log 显示数组对象的内容

如何console.log多个对象?