zoukankan      html  css  js  c++  java
  • console.log是异步的吗?

    今晚我加的一个前端群里有人问了这样一个问题,下面这段代码在Chrome中运行:

    <!DOCTYPE html>
    <html lang="en">
        <head>
        <meta charset="UTF-8">
        <title></title>
        </head>
        <body>
        <script>
                var a = {name: '1'};
                console.log(a);
                a.name = '2';
                console.log(a);
        </script>
        </body>
    </html>
    

    打开控制台后,却发现运行结果是这样的:

    Object
        name: "2"
        __proto__: Object
    Object
        name: "2"
        __proto__: Object
    

    这个结果不符合我们所期望的第一个输出是name: "1"

    难道console.log是异步的?

    可是当我将那段JavaScript代码粘贴到控制台直接运行,或是打开控制台后刷新一遍网页,运行结果就会变成:

    Object {name: "1"}
    Object {name: "2"}
    

    这正是我们所期望的结果。

    为什么会这样?

    因为代码在运行的时候控制台没有打开

    首先明确一点,a所储存的是一个引用类型值的地址,所有对a的操作都会具体到这个地址所对应的那个对象上。其次,console并不是JavaScript提供的对象,而是浏览器的控制台提供的。这具体到不同的浏览器,比如Chrome中是由Devtool的控制台提供,Firefox中是由Firebug的控制台提供。

    在Chrome中,console.log在控制台打开后才起作用,也就是说,当你打开控制台时,console.log才会将之前被传进去的参打印出来。
    那么问题来了,在上述代码中,传进console.log中的参是一个地址,当代码执行完毕后,打开控制台,console.log开始起作用,那么它打印出的实际上是已经做完全部处理后的对象。这就相当于这样的执行顺序:

    var a = {name: '1'};
    a.name = '2';
    console.log(a);
    console.log(a);
    

    如果是打开控制台再运行代码,那么console.log是直接起作用的,代码会顺序执行,所以所看到的结果是符合期望的。

    那么该如何解决这个问题?只能在执行的过程中创建新对象来曲线救国了:

    var a = {name: '1'};
    console.log(JSON.parse(JSON.stringify(a)));
    a.name = '2';
    console.log(JSON.parse(JSON.stringify(a)));
    

    这相当于帮浏览器对要被改变的对象存了个快照。

    当然,只要你开着控制台来执行代码,那么是不会出现这样的问题的。

    最后我认为这不是个BUG,相反这是个节省运算资源的行为。无论控制台是否打开console.log都起作用是十分不妥的。

    开着控制台还会出现不符合期望的结果才是BUG,然而早就被修复了。

  • 相关阅读:
    1029 旧键盘 (20 分)C、Java、python
    1028 人口普查 (20 分)C语言
    1027 打印沙漏 (20 分)C语言
    luoguP2709 小B的询问
    luoguP2709 小B的询问
    bzoj5016 [Snoi2017]一个简单的询问
    bzoj5016 [Snoi2017]一个简单的询问
    luoguP1972 [SDOI2009]HH的项链(莫队)
    luoguP1972 [SDOI2009]HH的项链(莫队)
    Tyvj1091
  • 原文地址:https://www.cnblogs.com/sevenskey/p/5476386.html
Copyright © 2011-2022 走看看