如何定制 console.log 的打印结果?

2022-10-27 17:09:00 +08:00
 yezheyu

前端新手,见笑

console.log()的输出对象结果由什么决定呢?我本以为是由被打印对象身上的 toString 方法,结果发现不是

如打印对象和数组

靠什么决定 log 数组就是输出其键值对和 length ,而对象只输出键值对?

对于打印 Vue 的实例,vue 是怎么让打印的结果除了打印对象的键值对,还打印了一堆像$attrs,$el之类的属性呢?

能重写 console.log 吗?定制自己的 log ,指定输出哪些属性

3113 次点击
所在节点    程序员
23 条回复
Kaier
2022-10-27 17:12:56 +08:00
aop 了解一下
Great233
2022-10-27 17:39:14 +08:00
> console.log()的输出对象结果由什么决定呢?
浏览器的本身实现

数组那叫数组元素和长度,也不叫键,叫下标,length 是 Array 的属性
对象是输出的对象属性和值

> 对于打印 Vue 的实例,vue 是怎么让打印的结果除了打印对象的键值对,还打印了一堆像$attrs,$el 之类的属性呢
$attrs $el 本身就是 Vue 实例对象的属性

重写 console.log
const originalConsoleLog = window.console.log;
window.console.log = function(...args) {
// 在这里定制
originalConsoleLog(...args);
}

MDN https://developer.mozilla.org/zh-CN/docs/Web/API/Console
musi
2022-10-27 18:21:24 +08:00
我觉得你应该了解的是 JavaScript 中的数组和对象,而不是 log
在 JavaScript 中数组也是对象,log 对数组和对象的表现是一致的
yezheyu
2022-10-27 18:25:41 +08:00
@Great233 可能我描述的不准确

对比普通的对象实例

![]( https://www.hualigs.cn/image/635a5993846fa.jpg)

它打印出来的只有{ }中间的属性

按我理解打印 vue 实例就应该像上面的 tom 那样

这个图中显示的属性就应该只显示下面图中 {} 中的属性

![]( https://www.hualigs.cn/image/635a5c08bf7ea.jpg)

[img]https://www.hualigs.cn/image/635a5aafcfcf3.jpg[/img]



但我看 $el 也不在 { } 中,也非 defineProperty 定义的 getter 属性,为啥会打印出来
Great233
2022-10-27 18:30:20 +08:00
@yezheyu 你有没有发现。。。https://www.hualigs.cn/image/635a5aafcfcf3.jpg 这个图是有 '...' 的。。

vue 实例也是一个普通对象实例,像你说的 $el $attr 也只是 vue 实例的一个普通属性而已,就像你 User 的 name 一样
yezheyu
2022-10-27 18:38:34 +08:00
@Great233 谢谢老哥

![](www.hualigs.cn/image/635a5c08bf7ea.jpg)

所以这部分也会存在对象里面嵌套的属性,这里显示的属性不全都是 vm 直接打点就能调用,对吗?
Great233
2022-10-27 18:46:54 +08:00
@yezheyu vm.xx.yy.zz 这样子
另外我认为你应该如 #3 所说去关注 js 中的各种类型而不是纠结 log 输出是什么样的,它只是一套控制台调试接口
yezheyu
2022-10-27 18:57:14 +08:00
@Great233

仔细想想,才发现是我自己理解错了

只有第一行的结果是 console.log 打印的结果,下面点开的属性是浏览器帮忙提取出来是吗?

我一直错误的以为下面点开的那部分也是打印的结果

所以一直很奇怪,为啥数组也算是对象的一种,为啥其打印出来会多打印一个 length ,原来是浏览器判断你打印的是数组,所以就帮你提取一个 length

这都是浏览器的行为,不是 console.log 帮我多打印一个 length

我理解的对吗
Great233
2022-10-27 19:08:16 +08:00
@yezheyu 展开后的结果也是属于打印的输出啊,因为内容过多所以一开始是折叠起来的
也就是说,你展开后的内容也不是浏览器帮你提取出来的,它们本身就属于你打印的那个对象
JS 中数组确实是对象的一种,length 就是数组的属性,而不是浏览器帮你提取的,在 JS 中,一切皆对象
定义数组 arr = [1,2,3] 与 arr = new Array(1, 2, 3) 是一样的
Great233
2022-10-27 19:13:07 +08:00
valkyrjaE
2022-10-27 19:51:39 +08:00
提个其他的建议,我感觉 op 需要提高表述能力。确实一眼看不懂你想问的是什么
yezheyu
2022-10-27 19:59:37 +08:00
@Great233 我在 node 中试了试,console.log 就是只有浏览器中第一行的输出结果,打印数组也不会多打印 length 属性
yezheyu
2022-10-27 20:00:50 +08:00
@valkyrjaE
确实,我不太知道怎么清楚准确的描述这个问题,我的问题
Great233
2022-10-27 20:24:49 +08:00
@yezheyu 那只是 node 与浏览器的实现不同,JS 只是提供了调试所用的 console api ,具体实现是各个平台实现的
lisongeee
2022-10-27 20:32:01 +08:00
如果重写或者间接调用 console.log ,那么控制台记录的右侧的代码行数就失去意义了

![image]( https://user-images.githubusercontent.com/38517192/198284852-41ff1a0b-e329-4426-a9b0-874525cbea61.png)
churchill
2022-10-27 20:35:53 +08:00
console api 确实有标准
https://console.spec.whatwg.org/#formatter
浏览器中改变不了什么,nodejs 可以做一些自定义
https://nodejs.org/api/util.html#utilinspectcustom
Great233
2022-10-27 20:38:00 +08:00
@yezheyu 回到你最初的问题,console.log 输出的对象结果是由什么决定的?
这是由各个平台对 console.log 的不同实现决定的,但它只是跟你输出的格式有关,与对象本身拥有哪些属性是无关的。
也就是说像 $attrs $el 这些,是 Vue 实例对象本身就有的属性,跟 console.log 无关。
甚至你也可以使用像我上面所说的 hack 的方式来让 console.log 不打印出这些属性。
bojackhorseman
2022-10-27 21:28:23 +08:00
在 vue 项目里打印是会多很多 getter ,甚至要一个一个点开,很麻烦。
解决办法就是用…
比如 console.log({...obj})
Kasumi20
2022-10-27 21:37:11 +08:00
那必须是由浏览器和 node.js 决定
stefanieewu
2022-10-27 22:21:34 +08:00
window.devtoolsFormatters 了解一下

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/890446

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX