如何让 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.log
和 console.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】:
控制台中的> Object
不仅显示当前状态。它实际上是推迟读取对象及其属性,直到您展开它。
例如,
var test = a: true
console.log(test);
setTimeout(function ()
test.a = false;
console.log(test);
, 4000);
然后展开第一个调用就正确了,如果你在第二个console.log
返回之前做的话
【讨论】:
以上是关于如何让 console.log 显示对象的当前状态?的主要内容,如果未能解决你的问题,请参考以下文章