“最简单的” 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 入门》。

相关实践学习
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
目录
相关文章
|
机器学习/深度学习 人工智能 安全
AI与网络安全:防御黑客的新武器
在数字化时代,网络安全面临巨大挑战。本文探讨了人工智能(AI)在网络安全中的应用,包括威胁识别、自动化防御、漏洞发现和预测分析,展示了AI如何提升防御效率和准确性,成为对抗网络威胁的强大工具。
|
前端开发 JavaScript
除了 jsPDF,还有哪些前端库可以用于生成 PDF?
【10月更文挑战第21天】这些前端库都有各自的特点和优势,你可以根据具体的项目需求、技术栈以及对功能的要求来选择合适的库。不同的库在使用方法、性能表现以及功能支持上可能会有所差异,需要根据实际情况进行评估和选择。
|
前端开发 API
前端界面生成PDF并导出下载
【10月更文挑战第21天】利用合适的第三方库,你可以在前端轻松实现界面生成 PDF 并导出下载的功能,为用户提供更方便的文档分享和保存方式。你还可以根据具体的需求进一步优化和定制生成的 PDF 文件,以满足不同的业务场景要求。
|
JavaScript 前端开发
我为展开收起功能做了动画,被老板称赞!
【8月更文挑战第23天】我为展开收起功能做了动画,被老板称赞!
448 1
我为展开收起功能做了动画,被老板称赞!
|
数据采集 搜索推荐 算法
蚂蚁seo的蜘蛛池原理与如何使用?
《揭秘蜘蛛池:原理与使用方法全解析》深入介绍了蜘蛛池的概念、工作原理及使用技巧。蜘蛛池通过吸引搜索引擎蜘蛛频繁访问特定网页,提高网页收录速度和概率。文章详细解析了蜘蛛池的链接储备、吸引策略、爬行路径引导等核心机制,并提供了选择服务、提交链接、监测效果等实用指南,强调合法合规使用的重要性。
463 4
|
存储 安全 前端开发
在前端开发中需要考虑的常见web安全问题和攻击原理以及防范措施
在前端开发中需要考虑的常见web安全问题和攻击原理以及防范措施
1387 0
|
机器学习/深度学习 数据采集 运维
智能化运维:机器学习在故障预测中的应用
【7月更文挑战第16天】随着信息技术的飞速发展,企业对IT系统的依赖程度不断加深。传统的运维模式已经难以满足现代业务的需求,智能化运维应运而生。本文将探讨如何通过机器学习技术提高故障预测的准确性,减少系统停机时间,并提升运维效率。我们将分析机器学习在故障预测中的具体应用案例,讨论实施过程中的挑战与对策,以及评估机器学习模型的性能。文章旨在为运维人员提供一种全新的视角和方法,以期达到优化系统稳定性和提升用户体验的目的。
|
定位技术 API 开发工具
iOS语言本地化/国际化宝典
iOS语言本地化/国际化宝典
833 0
iOS语言本地化/国际化宝典
|
前端开发 JavaScript 机器人
详解《基于 javascript 的流程图编辑框架LogicFlow
详解《基于 javascript 的流程图编辑框架LogicFlow
2205 0
|
存储 缓存 JavaScript
libevent实战的那些坑
libevent实战的那些坑
713 0
libevent实战的那些坑