V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yezheyu
V2EX  ›  程序员

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

  •  
  •   yezheyu · 2022-10-27 17:09:00 +08:00 · 2747 次点击
    这是一个创建于 490 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前端新手,见笑

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

    如打印对象和数组

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

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

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

    23 条回复    2022-11-25 14:34:08 +08:00
    Kaier
        1
    Kaier  
       2022-10-27 17:12:56 +08:00
    aop 了解一下
    Great233
        2
    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
        3
    musi  
       2022-10-27 18:21:24 +08:00
    我觉得你应该了解的是 JavaScript 中的数组和对象,而不是 log
    在 JavaScript 中数组也是对象,log 对数组和对象的表现是一致的
    yezheyu
        4
    yezheyu  
    OP
       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
        5
    Great233  
       2022-10-27 18:30:20 +08:00
    @yezheyu 你有没有发现。。。https://www.hualigs.cn/image/635a5aafcfcf3.jpg 这个图是有 '...' 的。。

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

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

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

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

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

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

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

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

    我理解的对吗
    Great233
        9
    Great233  
       2022-10-27 19:08:16 +08:00 via iPhone
    @yezheyu 展开后的结果也是属于打印的输出啊,因为内容过多所以一开始是折叠起来的
    也就是说,你展开后的内容也不是浏览器帮你提取出来的,它们本身就属于你打印的那个对象
    JS 中数组确实是对象的一种,length 就是数组的属性,而不是浏览器帮你提取的,在 JS 中,一切皆对象
    定义数组 arr = [1,2,3] 与 arr = new Array(1, 2, 3) 是一样的
    valkyrjaE
        11
    valkyrjaE  
       2022-10-27 19:51:39 +08:00
    提个其他的建议,我感觉 op 需要提高表述能力。确实一眼看不懂你想问的是什么
    yezheyu
        12
    yezheyu  
    OP
       2022-10-27 19:59:37 +08:00 via iPhone
    @Great233 我在 node 中试了试,console.log 就是只有浏览器中第一行的输出结果,打印数组也不会多打印 length 属性
    yezheyu
        13
    yezheyu  
    OP
       2022-10-27 20:00:50 +08:00 via iPhone
    @valkyrjaE
    确实,我不太知道怎么清楚准确的描述这个问题,我的问题
    Great233
        14
    Great233  
       2022-10-27 20:24:49 +08:00 via iPhone
    @yezheyu 那只是 node 与浏览器的实现不同,JS 只是提供了调试所用的 console api ,具体实现是各个平台实现的
    lisongeee
        15
    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
        16
    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
        17
    Great233  
       2022-10-27 20:38:00 +08:00 via iPhone
    @yezheyu 回到你最初的问题,console.log 输出的对象结果是由什么决定的?
    这是由各个平台对 console.log 的不同实现决定的,但它只是跟你输出的格式有关,与对象本身拥有哪些属性是无关的。
    也就是说像 $attrs $el 这些,是 Vue 实例对象本身就有的属性,跟 console.log 无关。
    甚至你也可以使用像我上面所说的 hack 的方式来让 console.log 不打印出这些属性。
    bojackhorseman
        18
    bojackhorseman  
       2022-10-27 21:28:23 +08:00 via iPhone   ❤️ 2
    在 vue 项目里打印是会多很多 getter ,甚至要一个一个点开,很麻烦。
    解决办法就是用…
    比如 console.log({...obj})
    Kasumi20
        19
    Kasumi20  
       2022-10-27 21:37:11 +08:00
    那必须是由浏览器和 node.js 决定
    stefanieewu
        20
    stefanieewu  
       2022-10-27 22:21:34 +08:00   ❤️ 1
    window.devtoolsFormatters 了解一下
    yezheyu
        21
    yezheyu  
    OP
       2022-10-28 09:36:16 +08:00
    @stefanieewu

    谢谢!这就是我本意想问的答案,怪我描述不清,害的大家误解我的意思


    还有,也多谢 @Great233 老哥的耐心解答
    learningman
        22
    learningman  
       2022-10-28 09:51:42 +08:00
    @lisongeee #15 Error.captureStackTrace 包一下试试?
    yezheyu
        23
    yezheyu  
    OP
       2022-11-25 14:34:08 +08:00
    @Great233

    再次感谢老哥,最近重新看了 Object 上 Object.getOwnPropertyDescriptors() API ,其中提到了属性的是否可枚举,我才算彻底明白这个问题,也明白了是我当初这个问题问歪了,哈哈
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3168 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 12:30 · PVG 20:30 · LAX 04:30 · JFK 07:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.