推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
abcbuzhiming

浏览器端的 console.log 是借助渲染引擎实现的吗?并不是真正的“打印命令行”?

  •  1
     
  •   abcbuzhiming · Jul 13, 2018 · 6248 views
    This topic created in 2871 days ago, the information mentioned may be changed or developed.
    以前我一直以为,浏览器端的 console.log 是一个真的“同步输出命令行”。就和其它大部分语言一样,你给它什么值,它就立刻打印到屏幕上去。但是最近在开发中发现的一个 bug 引发的现象,让我产生了疑问:
    这个 bug 是这样的,从服务器拿到的数据。服务器端打印的结果,和浏览器端最终的结果不一样,哪怕在浏览器端拿到数据后立即 console.log 输出,发现值也是和服务端给的不一样,研究了半天发现是在渲染代码里无意中少写了=号导致数据被改变了。但是有一点:console.log 可是在渲染代码之前就执行了的,然而输出到控制台上的数据却依旧是被篡改后的。这种现象的唯一解释是控制台其实是归浏览器的渲染引擎管的,就和渲染 DOM 是一条线,在 js 代码本身没执行完之前,console.log 并不会真正的输出内容。请问各位是不是这样?
    26 replies    2018-07-14 18:00:54 +08:00
    TheOutgoing
        1
    TheOutgoing  
       Jul 13, 2018
    不是
    marcong95
        2
    marcong95  
       Jul 13, 2018
    console.log 是异步的这个应该不假,我也遇到过类似情况
    invalidtoken
        3
    invalidtoken  
       Jul 13, 2018 via Android
    如果是对象的话,后面有个 i 图标,放上去会有 “ Value below was evaluated just now ” 这个提示
    KeepPro
        4
    KeepPro  
       Jul 13, 2018   ❤️ 1
    并不是。比如:
    a = 1
    console.log(a)
    a = 2
    console.log(a)
    你所遇到的情况,应该是你用 console.log 输出了一个 Object,
    在输出的时候,浏览器工具拿这个 Object 的引用去取值的。
    有点像函数调用时候的 值传递 还是 引用传递的 区别。
    grewer
        5
    grewer  
       Jul 13, 2018
    才发现,看来是新手
    pabupa
        6
    pabupa  
       Jul 13, 2018 via Android
    是异步的~
    yimity
        7
    yimity  
       Jul 13, 2018 via Android
    你应该打印的是 object
    cuzfinal
        8
    cuzfinal  
       Jul 13, 2018
    什么鬼?
    肯定是你代码写的有问题。
    meteor957
        9
    meteor957  
       Jul 13, 2018 via Android
    到底是不是异步啊,楼上的大佬意见都不统一吗
    Stop
        10
    Stop  
       Jul 13, 2018   ❤️ 3
    当然是同步的 你打印 console.log(JSON.stringify(……))试试
    ThomasChan
        11
    ThomasChan  
       Jul 13, 2018
    7 楼说的对,如果打印的是 array, object,打印的实际上是引用值
    codehz
        12
    codehz  
       Jul 13, 2018
    console.log 的参数肯定是同步求值的。但是求出来的值肯定是被异步读取的(所以引用对象的话,可能就会产生变化
    grantonzhuang
        13
    grantonzhuang  
       Jul 13, 2018 via Android
    我的猜想,浏览器本质上也是个 GUI 程序,有定时重新渲染的机制,传给 console.log 的是一个引用,刷新的时候会重新去获取引用引用的值
    CDL
        14
    CDL  
       Jul 13, 2018
    输出的 object 也是对象引用,完
    abcbuzhiming
        15
    abcbuzhiming  
    OP
       Jul 13, 2018
    @invalidtoken 是的,后面有“ Value below was evaluated just now ”

    @KeepPro 我很奇怪的是这是 js 独有的吗,在别的语言我没发现这个现象,输出时多少就是多少


    @codehz 我是头一次发现有语言是这么干的
    var AAA = {b:1};
    console.log(AAA);
    AAA.b=2;
    像这样的代码,打印的话难道不应该就是打印时的值吗,为啥会是引用的值
    AlisaDestiny
        16
    AlisaDestiny  
       Jul 13, 2018
    如果你知道浏览器的控制台可以输出图片那么你心里就有答案了。
    codehz
        17
    codehz  
       Jul 13, 2018
    @abcbuzhiming #15 因为 console.log 并不是给用户看的。。。
    所以要保证尽可能减少消耗。。一个 dom 对象要完整的输出出来(不算循环引用的部分),比重新渲染一个网页的消耗都要大(一般情况),比如你看看 document 对象的属性数量。。。
    更别说还有原型链上的一堆东西。。。
    abcbuzhiming
        18
    abcbuzhiming  
    OP
       Jul 13, 2018
    @AlisaDestiny 你的意思是说这确实是浏览器 DOM 渲染发生时间原理造成的?


    @codehz 这到底是 js 的特性还是浏览器特性,我还没来得及做试验,服务器的 NodeJS 也是这样的吗?那以后真得小心点,我接触过不少编程语言了,这个 console.log 的输出特性和绝大部分语言的控制台输出都不一样。我还没找到和它类似的
    codehz
        19
    codehz  
       Jul 13, 2018
    NodeJS 的 console.log 当然是即时输出的,
    airdge
        20
    airdge  
       Jul 13, 2018
    nodejs:全局的 console 对象的方法既不总是同步的(如浏览器中类似的 API ),也不总是异步的(如其他 Node.js 流)

    http://nodejs.cn/api//console.html
    autoxbc
        21
    autoxbc  
       Jul 13, 2018 via iPhone
    引用对象和其原型链形成了一个十分巨大的树形结构,没有办法简单对其做快照,所以希望 console.log 输出引用类型的某一时刻状态是不现实的

    夸张点说,每快照一次,需要保存整个引擎所在内存
    lookas2001
        22
    lookas2001  
       Jul 14, 2018 via Android
    输出对象的话是一个引用,然后查看的时候一步一步展开。这点就如 3 楼提示的那样。
    如果输出一个数字一个字符串啥的就不会有这种问题。
    想想都是泪,当时我也遇到过这样的情况,差错查了整整一天。(无奈)
    royzxq
        23
    royzxq  
       Jul 14, 2018
    恭喜踩坑 1/?
    wly19960911
        24
    wly19960911  
       Jul 14, 2018 via Android
    如果真的想定位当前位置的值,用 debugger 或者 console.log 定位代码然后断点,console.log 出来的值,会异步读取,造成读值的偏差。
    abcbuzhiming
        25
    abcbuzhiming  
    OP
       Jul 14, 2018
    @airdge 了解了,谢谢,天坑啊这是
    msg7086
        26
    msg7086  
       Jul 14, 2018
    #15 其他语言里连打印对象功能都没有,当然也就没有这个现象了。
    你想想,别的语言里是不是都是打印出字符串的?
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   3032 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 88ms · UTC 02:59 · PVG 10:59 · LAX 19:59 · JFK 22:59
    ♥ Do have faith in what you're doing.