前端页面,用 JavaScript 在调试 Bug 时有哪些奇技淫巧?
1 debugger
只要在代码中添加debugger,chrome在运行的时候会自动停在那里。还可以用条件语句把它包裹起来,这样就可以在需要的时候才执行它。
if (thisThing) {
debugger;
}
2 console功能
调试时console.log是最常用的命令之一,此外还有一些其他的使用的功能
2.1 console.log
在console.log()中,可以用%s设置字符串,%i设置数字,%c设置自定义样式,console.log()接受的两个参数,前者是描述性的语言,而第二个参数是与第一个参数位置对应的字符
console.log(' %c %s %s %s', 'color: yellow; background-color: black;', '–', '测试信息', '–');
2.2 console.table()
很多的时候,你可能会有一堆对象需要查看。可以用console.log把每一个对象都输出出来,也可以用console.table语句直接把所有的对象都直接输出成为一个表格
2.3 console.time()和console.timeEnd()
当想知道某些代码的执行时间的时候这个工具将会非常有用,特别是当你定位很耗时的循环的时候。
2.4 console.trace()
console.trace()会显示函数调用的完整的堆栈轨迹信息
getTopN2(arr, n) {
// sort参数返回值大于1,就交换位置
console.trace('getTopN2');
return [...arr].sort((a, b) => b - a).slice(0, n)
}
结果如下:
3 DOM节点变化时中断代码运行
在调试DOM节点时,可以在Chrome的Elements界面,右键点击某个元素,选择Break on选项,可以在子节点变化时中断、在元素属性变化时中断或者在节点被移除时中断代码运行
4 在控制台设置断点
4.1 快捷键
- F8: 跳转至下个断点
- F10: step over, 单步执行, 不进入函数
- F11: step into, 单步执行, 进入函数
- shift + F11: step out, 跳出函数
4.2 在代码上设置断点
对于每个已添加的断点都有两种状态:激活和禁用。刚添加的断点都是激活状态,禁用状态就是保留断点但临时取消该断点功能。
在Breakpoints列表中每个断点前面都有一个复选框,取消选中就将禁用该断点。断点位置的右键菜单中也可以禁用断点。也可以在右侧功能区上面Chrome断点设置钮临时禁用所有已添加的断点,再点一下恢复原状态。
4.3 逐步执行
每点击一次,JS语句往后执行依据,F11
4.4 逐过程执行
和“逐语句执行”按钮不同,“逐过程执行”按钮常用在一个方法调用多个JS文件时,涉及到的JS代码比较长,则会使用到这个按钮。
在复杂的JS文件中,F11会进入到jQuery等工具库文件的内容,点击逐过程执行的按钮就可以跳过框架的JS脚本了
4.5 条件断点
已有断点位置的右键菜单中选择“Add Breakpoint…”或者空白位置右键出现的菜单选择“Add Conditional Breakpoint”,可以设置触发断点的条件,就是写一个表达式,表达式为true时才触发断点。
可以用条件断点代替在代码中的console.log
5 调用栈(Call Stack)
在断点停下来时,右侧调试区的Call Stack会显示当前断点所处的方法调用栈,比如有一个函数g()其中又调用了函数f(),而我在f()中设置了一个断点,那么执行函数g()的时候会触发断点,其调用栈显示如下:
最上面是f(),然后是g()。调用栈中的每一层叫做一个frame,点击每个frame可以跳到该 frame 的调用点上。
此外,还可以在frame上用右键菜单重新开始执行当前frame,也就是从该frame的开始处执行。比如在函数f()的frame上Restart Frame, 断点就会跳到f()的开头重新执行,context中的变量值也会还原。
这样结合变量修改和编辑代码等功能,就可以在当前frame中反复进行调试,而不用刷新页面重新触发断点了。
6 查看变量
Call Stack列表的下方是Scope Variables列表,在这里可以查看此时局部变量和全局变量的值。
7 临时修改 JavaScript 代码
Chrome中可以临时修改JS文件中的内容,保存(Ctrl+S)就可以立即生效,结合Console等功能就可以立即重新调试了。但注意这个修改是临时的,刷新页面修改就没了。
8 在页面操作时触发断点
在Source面板,右下角Event Listener Breakpoints菜单,选择不同的类型的DOM事件,可以在页面上发生对应的事件时,触发断点
9 Copy As Fetch复制为 Fetch
在Network标签下的所有的请求,都可以复制为一个完整的Fetch请求的代码。
操作:
- 在Network标签页中,选中一个请求
- 右击,选择Copy --> Copy as fetch
10 截屏
在新版本的Chrome中,提供了一个截图的API,你可以将整个页面截图或者截取部分页面元素,且截取的图片尺寸跟浏览器当前视图中要截取的内容所占尺寸一致。截图输出的是png格式的图片,会自动通过浏览器下载到默认的目录下。现在有三种截取的方式:截取整个页面、部分元素 或 当前视图。
- CMD + SHIFT + P(windows中用CTRL + SHIFT + P) 打开命令菜单
- 在Elements标签页,选中要截取的页面元素
- 选择Capture node screenshot(或者Capture full size screenshot或者Capture screenshot)
11复制变量
不管是在Network面板还是在Sources面板获得的变量,如果想要拷贝出来都可这样做:
(1)右键点击这个变量,选择Store as global varible,如果之前没有进行过这样的操作,那么想要拷贝的变量就会被复制到temp1这个全局变量中
(2)在控制台输入copy(temp1),这时候这个变量就被复制到了剪贴板
(3)在需要的地方粘贴即可
参考
- 韩国凯的博客 - Chrome 中的 JavaScript 断点设置和调试技巧
- CSDN - 利用chrome浏览器调试js断点的2点心得
- 知乎 - 前端程序员不知道的14个JavaScript调试技巧
- 知乎 - 聊聊Chrome DevTools中你可能不知道的调试技巧
- 前端页面,用 JavaScript 在调试 Bug 时有哪些奇技淫巧?@知乎
更多笔记分享
- 认识JavaScript / 注释以及输入输出语句 / 变量的使用、语法扩展、命名规范
- 数据类型简介以及简单的数据类型 / 获取变量数据类型/运算符&算数运算符 / 递增和递减运算符
- 比较运算符和逻辑运算符 / 赋值运算符以及运算符优先级 / 流程控制-实际案例学习if语句
- 三元表达式&分支流程控制 switch 语句 / JavaScript的for循环学不明白怎么办?
- 以案例学习JavaScript双重for循环 /while以及do while循环
- 遍历数组,附5个案例 / 函数的概念和使用/JavaScript函数的参数
- JavaScript的返回值 / 函数案例练习 / JavaScript函数的两种声明方式 / JavaScript 作用域
- 对象
JavaScript最全拔高(更新中)
JavaScript面向对象开发相关模式 / JavaScript创建对象简单方式到优化 / JavaScript面向对象游戏案例:贪吃蛇