放弃 console.log 吧!用 Debugger 你能读懂各种源码

Posted cybozu开发者

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了放弃 console.log 吧!用 Debugger 你能读懂各种源码相关的知识,希望对你有一定的参考价值。

很多同学不知道为什么要用 debugger 来调试,console.log 不行么?

还有,会用 debugger 了,还是有很多代码看不懂,如何调试复杂源码呢?

这篇文章就来讲一下为什么要用这些调试工具:

console.log vs Debugger

相信绝大多数同学使用 console.log 调试的,把想看的变量值打印在控制台。

这样能满足需求,但是遇到对象的打印就不行了。

比如我想看 webpack 源码里的 compilation 对象的值,我打印了一下:

但你会发现对象的值也是对象的时候不会展开,而是打印一个 [Object] [Array] 这种字符串。

更致命的是打印的太长会超过缓冲区的大小,terminal 里会显示不全:

而你用 debugger 来跑,在这里打个断点来看就没这些问题了:

有的同学可能会说,那打印一个简单的值的时候用 console.log 还是很方便呀。

比如这样:

真的么?

那还不如用 logpoint:

 

代码执行到这里就会打印:

而且没有污染代码,用 console.log 的话调试完之后这个 console 不也得删掉么?

但是 logpoint 不用,它就是个断点的设置,不在代码里。

当然,最重要的是 Debugger 调试是可以看到调用栈和作用域的!

首先是调用栈,它就是代码的执行路线。

比如这个 App 的函数组件,你可以看到渲染这个函数组件会经历 workLoop、beginWork、renderWithHooks 这些流程:

你可以点开调用栈的每一帧看下都执行了啥逻辑,用到啥数据。比如可以看到这个函数组件的 fiber 节点:

再就是作用域,点击每一个栈帧就可以看到每个函数的作用域中的变量:

可以看到调用栈来理清出错前都走了哪些代码,可以通过作用域来看到每一个变量的值。

有了这些东西,排查错误不就很轻松了么!

而你用 console.log 呢?

啥也没,只能自己猜。

由于本篇文章都是gif动图,今天上传太累了,要看全文,请点击以下链接:https://cybozudev.kf5.com/hc/community/question/34258651/

js的线程和同步异步以及console.log机制

  项目上线了,闲下来就写写东西吧。积累了好多东西都没有做笔记~挑几个印象深刻的记录一下吧。

js的同步异步以及单线程问题:

               都知道单线程是js的一大特性。但是通常io(ajax获取服务器数据)、用户/浏览器自执行事件(onclick、onload、onkeyup等等)以及定时器(setTimeout、setInterval)这些异步操作又是怎样工作的呢。

              我们把js的任务分为两种:同步任务,异步任务:

                                                              举个例子吧:   let a=1;

                                                                                       console.log("同步任务");

                                                                                      setTimeout(()=>{console.log("异步任务1");},0);

                                                                                      setTimeout(()=>{console.log("异步任务2");},100);

           这样就应该都很明白了,那么他们是怎么在单线程里面工作的呢?

                                                               1、其实js会先将所有的同步任务推入到执行栈中;

                                                                2、执行栈中的任务全部执行完毕;(如果error导致阻塞,那么将影响到步骤3)

                                                                3、将异步任务(setTimeout)按时间顺序推入任务队列中;

                                                                4、执行异步任务;

         ps:很明显setTimeout和setInterval并不是完全精确。https://github.com/woai30231/javascriptThreadStudy(javascript线程及与线程有关的性能优化)

 

js console.log同步异步?:这个问题是在调试的时候遇到的,我发现有时候console.log并不会给我预期的结果,后来查查资料(参考《你不知道的javascript中卷》第二部分异步和性能 1.1 异步控制台部分)。

                  并没有什么规范或一组需求指定console.* 方法族如何工作——它们并不是JavaScript 正式的一部分,而是由宿主环境(请参考本书的“类型和语法”部分)添加到JavaScript 中的。因此,不同的浏览器

                 和JavaScript 环境可以按照自己的意愿来实现,有时候这会引起混淆。尤其要提出的是,在某些条件下,某些浏览器的console.log(..) 并不会把传入的内容立即输出。出现这种情况的主要原因是,在许

                多程序(不只是JavaScript)中,I/O 是非常低速的阻塞部分。所以,(从页面/UI 的角度来说)浏览器在后台异步处理控制台I/O 能够提高性能,这时用户甚至可能根本意识不到其发生。

          什么意思呢?我们还是举个例子来说:   var  a={name:"小Q"};

                                                                          console.log(a);

                                                                          a.name="snail";

         我们通常认为恰好在执行到console.log(..) 语句的时候会看到a 对象的快照,大多数情况下我们看到的是"小Q”,但是,有时候浏览器可能会吧控制台I/O延迟到后台,这时候我们看到的可能是"snail",到底什么

         时候控制台I/O 会延迟,甚至是否能够被观察到,这都是游移不定的。如果在调试的过程中遇到对象在console.log(..) 语句之后被修改,可你却看到了意料之外的结果,要意识到这可能是这种I/O 的异步化造成的。

         如果遇到这种少见的情况,最好的选择是在JavaScript 调试器中使用断点,而不要依赖控制台输出。次优的方案是把对象序列化到一个字符串中,以强制执行一次“快照”,比如通过JSON.stringify(..)。

以上是关于放弃 console.log 吧!用 Debugger 你能读懂各种源码的主要内容,如果未能解决你的问题,请参考以下文章

如何让 VueReact 代码的调试变得更爽

同学给我来个手写的new吧

不会还有人,还不知道js中字符串的所有方法吧

js的线程和同步异步以及console.log机制

关于Date的基础操作

[Node.js] 關於 console.log 的格式化輸出