调试是项目开发中非常重要的环节。掌握一些调试技巧,不仅能帮助我们定位到问题,还能提升我们的开发效率。本文从两个场景来介绍调试技巧:

  1. 代码报错。
  2. 逻辑出错。

调试代码报错的技巧

技巧1: 读懂报错信息

大部分情况下,能读懂错误信息与错误堆栈的信息,就知道是什么导致的错误。报错信息可以分为如下四类:

ReferenceError

引用类型错误。引用不存在的变量时会报这个错。如:

  1. console.log(a)

会报错: Uncaught ReferenceError: a is not defined。因为 a 被引用时,还没有被定义。

SyntaxError

语法错误。出现语法错误时会报这个错。如:

  1. let c == 5

会报错: Uncaught SyntaxError: Unexpected token '=='

TypeError

类型错误。值的类型与预期不一致时会报这个错。如:

  1. let data = await fetch('/api/list')
  2. data.list

如果 data 是 undefined。会报错:Uncaught TypeError: Cannot read property 'list' of undefined。预期是对象,实际是 undefined

再看下面的代码:

  1. doSth()
  2. function doSth(cb) {
  3. cb()
  4. }

会报:Uncaught TypeError: cb is not a function。预期是函数,实际不是。

RangeError

范围错误。当设置的数值超出相应的范围会报这个错。如:

  1. new Array(-1)。

会报: Uncaught RangeError: Invalid array length

技巧2: 二分法排错

有的报错,根据报错信息,无法定位到具体的代码。此时,可以用二分法来快速定位到报错的具体代码。具体做法如下:
two.png

如,在 React 开发中,常会碰到这样的错: Uncaught Invariant Violation: Minified React error #31;...。这是因为非法的 JSX 的节点导致的。二分法可以快速的找出有问题的 JSX。

技巧3: 打断点的技巧

可以在报错的前一行断点。可以查看当前作用域和上级作用域中,各个变量值。看是哪个导致的下一行的报错。
debug-info.jpg

上图中右侧的 Scope Tab 中的内容是作用域中变量的信息, Call Stack 是调用堆栈信息。

如果只有在某些情况下,才会报错,可以打条件断点。我习惯在代码里写条件断点:

  1. if (a > 5) {
  2. debugger
  3. }

调试逻辑出错的技巧

逻辑出错,常常是因为错误的条件判断,错误的循环退出条件和没控制好异步导致的。

找出逻辑出错的方式:

技巧1: 用断点找到问题代码

有时候,错误的逻辑会导致的预期之外的 DOM 变化。 或 接口的调用。这种情况下,可以通过设置 DOM 断点 来查找问题。DOM 断点 支持 3 种触发条件:

  1. Subtree Modified。 子元素发生变化时触发。
  2. Attribute Modified。 属性发生改变时触发。
  3. Node Removal。元素被删除时触发。

举个例子,要看元素为什么被错误的移除了,设置 DOM 断点,触发条件是 node removal。设置 DOM 断点 方式,右击目标元素,点击下图所示的菜单:
dom-breakpoint.jpg

有时候,错误的逻辑会导致的预期之外的接口调用。这种情况下,可以通过设置 XHR/fetch 断点 来查找问题。XHR/fetch 断点 的触发条件支持筛选接口地址。在开发者工具的 Source Tab,可以打 XHR/fetch 断点。 如下图所示:
xhr-breakpoint.gif

技巧2: 用断言找到出错的函数

我们给函数写覆盖率很高的单元测试来确保函数逻辑的正确性。但受限与团队的理念,写测试的不小的工作量,项目工期等原因,写测试的毕竟是少数。

console.assert() 来写些断言,是测试的低成本替代方案。只有在 console.assert() 的第一个参数是 false 时,向控制台输出第二个参数的内容。通过 console.assert() 输出的报错信息,来知道哪个函数出错了。例如:

  1. function sum(a, b) {
  2. // 代码实现
  3. }
  4. console.log(sum(1, 2) !== 3, `sum 函数逻辑错误`)

技巧3: 调试点击外侧消失的元素的样式

有的元素,在开发中工具去审查它的时候,它就消失了。可以通过断点会冻结 DOM 的特性来调试这元素。在控制台中,输入下面的代码:

  1. setTimeout(() => {debugger}, 2000)

然后,让元素显示。2秒会,会进断点,此时再去审查元素,因为 DOM 的更新被断点冻结住了,元素就不会消失。

推荐阅读