大家好,我是考100分的小小码 ,祝大家学习进步,加薪顺利呀。今天说一说一起console.log()引发的血案,希望您对编程的造诣更进一步.
案发现场:
let timing = window.performance.timing,
timingStr = JSON.stringify(timing),
domContentLoadedEventStart = timing.domContentLoadedEventStart
console.log("timing:", timing)
console.log("timingStr:", timingStr)
console.log("domContentLoadedEventStart:", domContentLoadedEventStart)
以上代码执行结果:
![一起console.log()引发的血案插图1 一起console.log()引发的血案](https://daima100.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
三种方式打印出来的值竟然不一样!
![一起console.log()引发的血案插图3 一起console.log()引发的血案](https://daima100.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
推断取证:
看上述结果:如果直接打印timing对象,可以拿到domContentLoadedEventStart的值,而经过JSON.stringify或者打印的是timing.domContentLoadedEventStart,值都不对。
- 难道是在这个三个console.log()执行的过程中,页面的performance.timing的值发生了改变,然后我将三个console.log()的执行顺序做了 调整,发现结果还是一样:只有直接打印timing拿到了值。
- 使用debugger看实时数据: 神奇的是,debugger状态下三种打印方式的值是相同的,timing.domContentLoadedEventStart都为0。
- 使用setTimeOut延时再使用三种打印方式,三个的值又全都有值,且值相同。
综合上述,不禁让我怀疑:console.log是不是异步执行?
真相:
果不其然,domContentLoadedEventStart前后值的不同果然和console.log()有关系。
原来, 控制台中console.log()是在打印对象的时候采用了懒加载的思路,在用户点击展开对象属性的时候,才会去获取该属性。所以就解释了为什么我们在控制台中看到的timing对象的domContentLoadedEventStart属性有值,而以字符串方式,或者直接打印该对象的value时为0。另外,在Chrome的控制台中,如果打印的对象,被改变过对象值,会在对象后面出现一个可点击的i号,点击这个i号,我们可以清楚的看见这个值,被改变了。
![一起console.log()引发的血案插图5 一起console.log()引发的血案](https://daima100.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
这下终于真相大白了。 不过console.log()也是我们debugger的一种非常有用的手段,但是如果打印出来的不是正确的值,反而会误导我们。最后,我去MDN上console.log()的API,原来MDN早就有打印对象时需要做特殊处理的说明。
![一起console.log()引发的血案插图7 一起console.log()引发的血案](https://daima100.com/wp-content/themes/justnews/themer/assets/images/lazy.png)
😔,还是我太年轻。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/13845.html