在Chrome中,console对象定义了两个方法,它们做的事情是一样的:

console.log(...)
console.dir(...)

我在网上读到过,dir在记录对象之前获取了它的一个副本,而log只是将引用传递给控制台,这意味着当你去检查你记录的对象时,它可能已经改变了。然而,一些初步测试表明,两者之间并没有什么区别,而且它们都可能会显示与记录时不同的对象状态。

尝试在Chrome控制台(Ctrl+Shift+J)看看我的意思:

> o = { foo: 1 }
> console.log(o)
> o.foo = 2

现在,展开log语句下面的[Object],注意它显示了值为2的foo。如果使用dir而不是log重复这个实验,情况也是一样的。

我的问题是,为什么这两个看似相同的功能会出现在主机上?


当前回答

控制台标准(提交ef88ec7a39fdfe79481d7d8f2159e4a323e89648)目前调用控制台。在将JavaScript对象传递给Printer之前应用通用的JavaScript对象格式化(规范级操作),但是对于单参数console.log调用,规范最终会将JavaScript对象直接传递给Printer。

由于规范实际上将关于Printer操作的几乎所有内容都留给了实现,因此对于console.log()使用何种格式由他们自行决定。

其他回答

来自firebug网站 http://getfirebug.com/logging/

调用console.dir(object)将记录对象属性的交互式列表,如>—DOM选项卡的微型版本。

使用console.dir()输出一个可以点击浏览的对象,而不是.toString()版本,如下所示:

console.dir(obj/this/anything)

如何在Chrome控制台显示完整的对象?

我认为Firebug的做法与Chrome的开发工具不同。看起来Firebug为您提供了对象的字符串化版本。Dir给你一个可展开的对象。两者都提供了Chrome中的可扩展对象,我认为这就是困惑的来源。或者只是Chrome浏览器的一个bug。

在Chrome中,两者都做同样的事情。展开你的测试,我已经注意到Chrome得到对象的当前值,当你展开它。

> o = { foo: 1 }
> console.log(o)
Expand now, o.foo = 1
> o.foo = 2
o.foo is still displayed as 1 from previous lines

> o = { foo: 1 }
> console.log(o)
> o.foo = 2
Expand now, o.foo = 2

您可以使用以下方法来获得对象的字符串化版本,如果这是您想要看到的。这将在调用该行时显示对象,而不是在展开它时显示对象。

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

在Firefox中,这些函数的行为非常不同:log只打印出toString表示,而dir打印出可导航的树。

在Chrome中,log已经打印出一棵树——大多数时候。然而,Chrome的日志仍然字符串对象的某些类别,即使他们有属性。也许最明显的区别是正则表达式:

> console.log(/foo/);
/foo/

> console.dir(/foo/);
* /foo/
    global: false
    ignoreCase: false
    lastIndex: 0
    ...

你还可以看到数组(例如,console.dir([1,2,3]))的明显区别,它的日志记录与普通对象不同:

> console.log([1,2,3])
[1, 2, 3]

> console.dir([1,2,3])
* Array[3]
    0: 1
    1: 2
    2: 3
    length: 3
    * __proto__: Array[0]
        concat: function concat() { [native code] }
        constructor: function Array() { [native code] }
        entries: function entries() { [native code] }
        ...

DOM对象也表现出不同的行为,如另一个答案所述。

控制台标准(提交ef88ec7a39fdfe79481d7d8f2159e4a323e89648)目前调用控制台。在将JavaScript对象传递给Printer之前应用通用的JavaScript对象格式化(规范级操作),但是对于单参数console.log调用,规范最终会将JavaScript对象直接传递给Printer。

由于规范实际上将关于Printer操作的几乎所有内容都留给了实现,因此对于console.log()使用何种格式由他们自行决定。