【问题标题】:How can I make console.log show the current state of an object?如何让 console.log 显示对象的当前状态?
【发布时间】: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,它与日志条目有很大不同。记录对象时这样做比记录存储原始值的变量时更有意义。
  • 我以前怎么从来没有接触过这个?我觉得这很可怕

标签: javascript debugging logging console console.log


【解决方案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返回之前做的话

            【讨论】:

              猜你喜欢
              • 2014-05-28
              • 2012-10-21
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-04-14
              • 2015-02-05
              • 2018-02-12
              相关资源
              最近更新 更多