共计 1919 个字符,预计需要花费 5 分钟才能阅读完成。
前几天,群里有个敌人问了一个很有意思的问题:
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,会发现打印进去的后果是:
而如果在此基础上刷新浏览器,会发现打印的后果变成了这样:
这的确是个很不起眼然而很有意思的问题 —— 为什么 Chrome 没有在第一次的时候就间接打印 {say:f}
,而是像 console.dir
那样打印出一个不具备对象属性预览的 Object
?
兴许这样做是有什么益处,不过先让咱们排除一些不必要的烦扰因素。第一个是:是否和原型相干?尽管群友给的案例代码波及到了原型,但其实和原型没有任何关系。我尝试将代码改为简略的 console.log({a:1})
后,仍然会产生同样的状况 —— 即第一次只打印 Object
,刷新之后才打印 {a:1}
。第二个是:是否和浏览器相干?目前为止运行代码的环境都是 Chrome,在其它浏览器下打印后果会是怎么样的呢?
在 FireFox 下,发现刷新前后都是间接打印对象属性预览:
在 Edge 下,发现刷新前后存在相似 Chrome 的差别:
那么,Chrome 这样做的目标是什么呢?带着这个疑难,我先是来到 StackOverflow 发问,不过并没有失去称心的答复。尽管我竭力揭示回答者这道题的困惑之处在于刷新前后打印后果的差别,但他还是“跑题”了 …… 不过,他的答复中有一个中央引起了我的留神,就是“a very slow operation”。这的确是给出了一个思考的方向:Chrome 在一开始没有间接打印对象的预览,会不会是因为这是一个耗时操作呢?所以,兴许这是一个性能相干的问题?
接着我尝试到知乎发问,最终很惊喜地失去了大佬的回复 —— 这的确是一个为了性能优化而采取的行为:
点进答复里提供的链接看一下,有更加具体的解释:
简略地说,这个行为的差别不是因为刷新浏览器导致的,而是因为关上 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…
交换
目前专一于前端畛域和交互设计畛域的学习,酷爱分享和交换。感兴趣的敌人能够关注公众号,一起学习和提高。