“最简单的” console.log,你真的懂吗?

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 在这篇文章中,我想和你简单说说,在浏览器中 console.log 一些看起来不符合预期的表现,了解其背后的原因,以避免开发排错时不必要的困惑。

作者:UC 国际研发 江焘

image.png

前言

提起 console.log 方法,我们再熟悉不过了,许多初学者从第一行 console.log('Hello World') 开始学习 JavaScript(Say Hello to the world),但是有些时候 console.log 又显得有点“陌生”。

在这篇文章中,我想和你简单说说,在浏览器中 console.log 一些看起来不符合预期的表现,了解其背后的原因,以避免开发排错时不必要的困惑。

思考和观察

首先,新建 demo.html 文件,复制下方代码到文件中。

image.png

然后,以 4 种不同的步骤进行测试(所用浏览器为 Google Chrome)。

Case A
1.在 Chrome DevTools 保证关闭的状态下,使用 Chrome 浏览器打开 demo.html 文件。

2.观察控制台打印结果。

Case B

1.在 Chrome DevTools 保证打开的状态下,使用 Chrome 浏览器打开 demo.html 文件。

2.观察控制台打印结果。

Case C

1.打开 DevTools 的控制台。

2.拷贝下方代码到控制台中运行。

image.png

3.观察控制台打印结果。

Case D
1.打开 DevTools 的控制台。

2.拷贝下方代码到控制台中运行。

image.png

3.观察控制台打印结果。

Result

公布结果之前,建议大家可以先行思考一下答案,看看自己的答案和控制台结果是否一致呢?

image.png

尝试分析

不知道上面四种输出结果和你心中预期是否一致哈。

不管如何,看到 ABCD 四种结果,我们先不去看浏览器的 console.log 实现原理,来尝试分析一下:

1.面对情况 A,假设从来没有写过 console.log,猜测它是同步代码或者异步代码中的一种。那根据结果来看,我暂定 console.log 是异步执行的代码。

2.基于情况 A,再思考下情况 B。按照前面的猜测,console.log 应该是异步的,那为什么打印出来的结果看上去是浏览器会同步执行 console.log 方法呢?好吧,情况 A 初始状态是关闭 DevTools 的,而情况 B 初始状态是打开。继续猜测只有打开 DevTools 的情况下,console.log 才是同步执行。

3.根据前面的猜测,看到情况 C 觉得符合预期。

4.再看情况 D,又不符合预期了。打开 DevTools 的情况下,不是应该同步执行 console.log 的吗?再琢磨一下,打印出来是一个可以展开的对象,猜测展开它的时候,chrome 又会对它求一次值,这一次是显示它的属性。

了解原理

根据刚刚的尝试分析,我们发现一个头疼的问题:很难预测 console.log 打印出来的值会不会被 console.log 之后其他代码影响。

在某些条件下,某些浏览器的 console.log(...) 并不会把传入的内容立即输出。出现这种情况的主要原因是,在许多程序(不只是 JavaScript)中, I/O 是非常低速的阻塞部分。所以,(从页面 /UI 的角度来说)浏览器在后台异步处理控制台 I/O 能够提高性能,这时用户甚至可能根本意识不到其发生(更详细的解释可以参考《你不知道的 JavaScript(中卷)》之异步控制台)。

罗列出这四种情况,不是为了让读者去记忆各种不符合预期的情形。因为,并没有什么规范指定 console.log 方法如何执行(参阅 MDN console.log),它由宿主环境添加到 JavaScript 中。到底什么时候控制台 I/O 会延迟,甚至是否能够被观察到,这都是不确定的。因此非常不建议根据经验去判断浏览器中 console.log 的表现。

同时提一下,node 中 console.log 的表现和浏览器表现不一致,官网文档明确警告:

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

调试排错

开发中遇到 bug,思路清晰地去解决它是成功的第一步。

在浏览器中使用 console.log 遇到问题,了解原因,至少在下一次你想用 console.log 的时候,就可以做到心中有数。

对于经常使用 console.log 来排错的同学,可以考虑在遇到特殊情况的时候,使用更有效更快速的打断点调试方法。具体可以查阅《在 Chrome DevTools 中调试 JavaScript 入门》。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
2月前
|
JavaScript 前端开发
setTimeout(console.log(12345), 1000)___经典面试题
本文探讨了JavaScript中`setTimeout`函数的行为,解释了传递函数和函数调用作为`setTimeout`参数时的区别,并通过修改`console.log`函数来演示函数调用是如何立即执行的。
44 0
setTimeout(console.log(12345), 1000)___经典面试题
|
5月前
|
机器学习/深度学习 JavaScript 前端开发
你不知道的console.log用法
在JavaScript中,使用`console.log()`时,通过大括号能显示变量名和值。`console.table(data, columns)`用于格式化打印表格。常用方法包括:`console.log()`
52 0
|
6月前
|
Web App开发 XML JavaScript
控制台 console.log() 的乐趣
控制台 console.log() 的乐趣
107 1
控制台 console.log() 的乐趣
|
前端开发
还在console.log一把梭吗?console还有其他骚操作
相信很多童鞋在开发中都是使用console.log()进行调试,本篇文章介绍一下console对象中的一些其他方法,这里并不是常用的方法。
155 0
还在console.log一把梭吗?console还有其他骚操作
|
流计算
一招给你的log4j2日志穿件”花衣服“
一招给你的log4j2日志穿件”花衣服“
504 0
一招给你的log4j2日志穿件”花衣服“
|
前端开发 API 对象存储
5分钟教你使用 console.log 输出五彩斑斓的黑
5分钟教你使用 console.log 输出五彩斑斓的黑
3482 0
5分钟教你使用 console.log 输出五彩斑斓的黑
|
JavaScript C语言
console.log(a + a++ * ++ a)到底输出什么?
前言 有些小伙伴可能看到这道题目就已经蒙圈了!甚至可能看不懂这道题目在干什么。其实这是一道比较考察基础的面试题,当你明白原理之后,你可能会感觉这道题也就那么回事,但是如果你没有思绪,那你可能觉得这道题很难。 今天我们就来彻底看看这到底在做什么妖!
515 0
console.log(a + a++ * ++ a)到底输出什么?
|
XML 移动开发 Java
八十六、Log4j与Log4j2 你真的明白了吗?
八十六、Log4j与Log4j2 你真的明白了吗?
八十六、Log4j与Log4j2 你真的明白了吗?
|
安全 Java Maven
Log4j2 再爆雷,Log4j v2.17.0 横空出世。。。
Log4j2 这是没完没了了,栈长以为《玩大了!Log4j 2.x 再爆雷。。。》 Log4j 2.16.0 是最终终结版本了,没想到才过多久又爆雷了:
Log4j2 再爆雷,Log4j v2.17.0 横空出世。。。
|
Java Android开发
还在用 Log4j ?快用 Log4j2,性能太猛了!
环境 jdk:1.7.0_79 cpu:i5-4570@3.20GHz 4核 eclipse:3.7 操作系统:win7 准备
还在用 Log4j ?快用 Log4j2,性能太猛了!