打开DevTools先后,对象的打印有什么区别?

chrome-devtools

前几天,群里有个朋友问了一个颇有意思的问题:前端

function Person (myName, myAge) {
    this.name = myName;
    this.age = myAge;
}
Person.prototype = {
    say:function () {
        console. log(" prototype中的输出");
    }
}
let person = new Person("John" ,12);
console.log(Person.prototype);
console.log(Person.prototype.constructor);
console.log(person.__proto__);

就这段代码而言,第一次运行后打开 Chrome 的 DevTools,会发现打印出来的结果是:git

1

而若是在此基础上刷新浏览器,会发现打印的结果变成了这样:github

2

这确实是个很不起眼可是颇有意思的问题 —— 为何 Chrome 没有在第一次的时候就直接打印 {say:f},而是像 console.dir 那样打印出一个不具有对象属性预览的 Objectchrome

也许这样作是有什么好处,不过先让咱们排除一些没必要要的干扰因素。第一个是:是否和原型相关?虽然群友给的案例代码涉及到了原型,但其实和原型没有任何关系。我尝试将代码改成简单的 console.log({a:1})后,依然会发生一样的状况 —— 即第一次只打印 Object,刷新以后才打印 {a:1}。第二个是:是否和浏览器相关?目前为止运行代码的环境都是 Chrome,在其它浏览器下打印结果会是怎么样的呢?api

在 FireFox 下,发现刷新先后都是直接打印对象属性预览:浏览器

3

在 Edge 下,发现刷新先后存在相似 Chrome 的差别:性能优化

4

那么,Chrome 这样作的目的是什么呢?带着这个疑问,我先是来到 StackOverflow 提问,不过并无获得满意的回答。虽然我极力提醒回答者这道题的困惑之处在于刷新先后打印结果的差别,但他仍是“跑题”了......不过,他的回答中有一个地方引发了个人注意,就是“ a very slow operation”。这确实是给出了一个思考的方向:Chrome 在一开始没有直接打印对象的预览,会不会是由于这是一个耗时操做呢?因此,也许这是一个性能相关的问题?chrome-devtools

接着我尝试到知乎提问,最终很惊喜地获得了大佬的回复 —— 这确实是一个为了性能优化而采起的行为:性能

点进回答里提供的连接看一下,有更加详细的解释:学习

简单地说,这个行为的差别不是因为刷新浏览器致使的,而是因为打开 DevTools 致使的。咱们在第一次运行代码以后,对象就打印出来了,但此时尚未打开 DevTools,因此这部分打印的内容是暂时放在内存的缓冲区(buffer)中的。并且对一个普通的用户来讲,他极可能永远也不须要打开 DevTools,在这种状况下若仍然选择呈现预览对象,会对内存和 CPU 有必定的要求,考虑到这一点,在设计上会让此次的打印不呈现预览对象。

对咱们来讲,若是这一次打开 DevTools,咱们看到的就只会是 Object。可是,若是在打开以后再次刷新,那么咱们看到的就是所指望的 {a:1}。所以,这种行为差别是在“保留信息”和“减小内存占用”之间所作的权衡(trade-off)。

咱们还能够进一步验证一下:随便打开一个页面,而且打开控制台,而后把代码文件直接拖到该页面运行:

这时候会发现,控制台里是直接打印出 {a:1} 这样的预览对象的,这是由于在打印以前咱们就提早把 DevTools 打开了,这时候打印的对象并不会放在缓冲区中。

此外,回答里还提到一个叫作 ObjectPreview 的东西,它其实就是上面所讲的可以呈现对象属性预览的东西,其实是 cdp( ChromeDevToolsProtocol ) 协议的一个 api。cdp 协议容许咱们检测和调试 Chrome 浏览器,咱们所熟知的 ChromeDevTools 就是遵循这个协议的。从这点来讲,当咱们打开 DevTools 时,其实就已经在使用 cdp 协议了。

FireFox 可能认为这个优化对性能提高并非很明显,因此在设计上选择的是直接打印 ObjectPreview。固然不排除还有其它方面的考虑,具体的我就没有再深挖啦,毕竟咱也不是开发浏览器的,了解一下,知道有这么一个东西就行了。关键的是,此次的疑惑获得了一个比较官方而准确的解答,我认为这才是最大的收获。

参考:

https://www.zhihu.com/questio...

https://twitter.com/ziyunfei/...

https://chromedevtools.github...

交流

目前专一于前端领域和交互设计领域的学习,热爱分享和交流。感兴趣的朋友能够关注公众号,一块儿学习和进步。

Snipaste_2020-07-09_16-09-39.png

相关文章
相关标签/搜索