console.dir和console.log有什么区别?


357

在Chrome中,该console对象定义了两种似乎可以完成相同操作的方法:

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

我在网上阅读过某个地方,该地方dir在记录对象之前先获取了对象的副本,而log只是将引用传递给控制台,这意味着到您检查记录的对象时,它可能已更改。但是,一些初步测试表明,两者没有什么区别,而且它们都可能以与记录时不同的状态显示对象。

在Chrome控制台(Ctrl+ Shift+ J)中尝试此操作,以了解我的意思:

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

现在,展开[Object]下面的log语句,注意它显示foo的值为2。如果使用dir代替重复实验,则同样如此log

我的问题是,为什么这两个看似相同的功能存在console


65
尝试一下console.log([1,2])console.dir([1,2])您将看到区别。
菲利克斯·克林

在Firebug中,使用记录的对象的内容console.dir不会更改,因此差异很大。
Eugene Yarmash 2013年

3
注意console.dir():此功能是非标准的!因此,请勿在生产中使用它;)
fred727


1
@ user7393973很高兴找到!实际上,该图像来自下面的答案,因此实际上是在笔记本电脑上捕获的。很高兴将某些东西还给MDN。这是多么伟大的资源。
Drew Noakes

Answers:


352

在Firefox中,这些功能的行为截然不同:log仅打印toString表示形式,而dir打印可导航树。

在Chrome中,大多数情况下log已经打印出一棵树。但是,Chrome 仍然对某些类别的对象进行字符串化,即使它们具有属性。区别的最明显例子也许是正则表达式:log

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

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

您还可以看到与普通对象不同的数组(例如console.dir([1,2,3]))的明显区别log

> 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对象也表现出不同的行为,如另一个答案所述


11
不要忘记console.dir保留了对该对象的引用。您可能不想在生产中广泛使用它。它可能仅在显示控制台时才起作用。
Jean-Philippe Leclerc

在Ubuntu上的Chromium 45中,console.log似乎是简化的“ Firefox”版本,看起来像是toString树而不是树。我不确定他们何时更改它,但是他们做到了。
icedwater

3
@icedwater:取决于在调用时是打开控制台console.log还是稍后打开它。对真的。:-)
TJ Crowder

您还可以看到与Function有明显的区别。在chrome中,它将使用来打印Function源代码console.log,但是使用console.dir,您可以看到prototypearguments属性。

1
目前看来,console.logconsole.dir实际在返回同样表示[1,2,3]在Firefox。
xji

151

将DOM元素发送到控制台时,Chrome中存在另一个有用的区别。

注意:

  • console.log 在类似HTML的树中打印元素
  • console.dir 将元素打印在类似JSON的树中

具体来说,console.log对DOM元素给予特殊处理,而console.dir没有。在尝试查看DOM JS对象的完整表示时,这通常很有用。

Chrome控制台API参考中提供了有关此功能和其他功能的更多信息。



11
@ loneshark99实际上是另一回事。注意到他们截图中的网址了吗?他们复制了我的答案。但这很好,因为SO答案的许可证允许这样做,而且我还是喜欢MDN。
Drew Noakes

知道了,这就是我最初的想法,但后来想到了为什么他们会从这里复制。说得通 。好信息
loneshark99

4

我认为Firebug的做法与Chrome的开发工具不同。看起来Firebug为您提供了对象的字符串化版本,同时console.dir为您提供了可扩展的对象。两者都为您提供了Chrome中的可扩展对象,而我认为这可能是造成混乱的原因。或仅仅是Chrome中的错误。

在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));



0

遵循Felix Klings的建议,我在chrome浏览器中对其进行了尝试。

console.dir([1,2]) 给出以下输出:

Array[2]
 0: 1
 1: 2
 length: 2
 __proto__: Array[0]

虽然console.log([1,2])给出以下输出:

[1, 2]

因此,我认为console.dir()应该在数组和对象中获取更多信息,例如原型等。


0

console.log()和之间的区别console.dir()

简而言之,这是区别:

  • console.log(input):浏览器以格式正确的方式登录
  • console.dir(input):浏览器仅记录对象及其所有属性

例:

如下代码:

let obj = {a: 1, b: 2};
let DOMel = document.getElementById('foo');
let arr = [1,2,3];

console.log(DOMel);
console.dir(DOMel);

console.log(obj);
console.dir(obj);

console.log(arr);
console.dir(arr);

在Google开发工具中记录以下内容:

在此处输入图片说明


0

7个回答之前没有提到,console.dir支持额外的参数depthshowHidden,以及是否使用colors

特别值得关注的是depth,从理论上讲,它允许将对象遍历到超过所console.log支持的默认2个级别。

我之所以写“理论上的”,是因为在实践中,当我有一个猫鼬对象并运行console.log(mongoose)和时console.dir(mongoose, { depth: null }),输出是相同的。实际深入到mongoose对象中的使用util.inspect

import * as util from 'util';
console.log(util.inspect(myObject, {showHidden: false, depth: null}));
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.