现在Chrome浏览器无疑是最受前端青睐的工具,缘由除了界面简洁、大量的应用插件,良好的代码规范支持、强大的V8解释器以外,还由于Chrome开发者工具提供了大量的便捷功能,方便咱们前端调试代码,咱们在平常开发中是愈来愈离不开Chrome,是否熟练掌握Chrome调试技巧恐怕也会成为考量前端技术水平的标杆。javascript
介绍Chrome调试技巧的文章不少,本文结合我本身的开发经验,但愿从实际运用的角度为你们再一次谈一谈这些功能,也但愿对你们都有所帮助和启发。html
ctrl+p 项目中定位文件,如下查找VueJS库文件:vue
ctrl+shif+o 文件中定位成员函数,如下定位到VueJS的nextTick接口:java
Chrome在souces页面提供snippets一栏,这里咱们能够随时编写JS代码,运行结果会打印到控制台。代码是全局保存的,咱们在任何页面,包括新建标签页,均可以查看或运行这些代码。webpack
咱们再也不须要为了运行一小段JS代码而新建一个HTML页面。snippets的方便之处在于,你只须要打开chrome就能够编写一份任意页面均可以运行的JS代码,并且用过snippets都知道,snippets编辑器是能够和sublime text相媲美的。git
某次项目中,我须要将100多页的word文档导入到页面中。考虑后续样式编写,页面的HTML结构以下:github
<div class="help-page_row"> <h3 class="help-page_title">title</h3> <p class="help-page_desc">paragraph</p> <p class="help-page_desc">paragraph</p> </div>
手工将100多页的内容组合成上面的HTML结构太过耗费时间,不太现实,因此我决定使用JS来将文档内容的标题和段落解析出来,并进行HTML包装。web
因为不须要视图的支持,在snippets编写这段代码是最好的选择,通过几回调试修改,最终成果以下:chrome
最后,将Word文档内容复制到snippets中,执行解析函数,最终的解析出来的HTML结果打印到控制台:
snippets中可使用控制台的copy接口,解析结果直接拷贝到剪切板会更方便
使用snippets来完成这类轻量级工做时,不须要追求代码的可读性、可维护性,咱们的代码只须要在大部分场景下可以正常运行就足够了。
但为了知足大部分场景,代码也是须要反复调试修改。snippets最实用之处偏偏在于,随时编写,随时调试,随时修改!
在项目开发中,咱们可能须要将后台数据拷贝到本地,做为本地数据进行调试。
若是后台返回没有格式化的JSON数据,在本地调试中咱们不免会遇到手动修改数据的状况,格式不美观的JSON数据修改起来会异常困难。
说到JSON的格式化,咱们首先想到的是JSON.stringify的格式化功能,例如四个空格的缩进:
JSON.stringify({name: 'lxjwlt'}, null, 4);
每次格式化JSON数据都要编写这段代码实在太麻烦,咱们可使用chrome控制台的copy接口解决这一问题:
不只仅是对象,copy接口对任何数据均可以进行拷贝,这里利用的是copy在拷贝数组或对象过程当中,对数据进行美化的功能
若是咱们使用Webpack服务器工具webpack-dev-server访问项目的开发页面,咱们会发现,开发页面被内嵌到了iframe中进行渲染。
因为Chrome控制台默认的上下文是window.top
,控制台中没法直接对内嵌在iframe的开发页面进行操做。若是咱们想对iframe中的页面进行DOM操做,或者执行类库API,首先咱们经过contentWindow来获取到iframe的上下文,而后使用with语句进行调试:
// html <iframe id="iframe"></iframe> // 控制台 with (document.getElementById('iframe').contentWindow) { inspect(document.body); new Vue({ /* ... */ }); // do something... }
以上方法能够在任意浏览器上使用,但若是咱们使用的是Chrome浏览器,Chrome控制台的上下文切换功能会更加方便:
咱们将上下文切换到iframe中,控制台的代码都会基于iframe的上下文来执行。若是你用webpack-dev-server进行调试,你会感谢这个功能。
Chrome控制台提供debug接口,能够传入一个函数,当这个函数下次执行的时候,调试器会自动在该函数中进行断点调试。
咱们明明能够在代码中设置断点进行调试,为何要用到debug来设置,是为了舍弃鼠标用命令行装逼而已吗?
在我看来,debug函数还提供了定位功能,它可以让咱们很快的找到指定的函数。下面演示怎么调试VueJS的数据驱动,如何找到VueJS数据驱动的代码入口。
咱们都知道,VueJS的数据驱动是经过defineProperty方法对数据的getter和setter进行封装,在这个封装中实现数据变化驱动视图同步修改的功能。若是咱们想研究VueJS的数据驱动,那么首先要找到封装getter和setter的地方,咱们能够经过debug接口来进行定位。如下用getter方法举例。
首先咱们知道VueJS实例中的数据都是映射_data
属性中的值:
var vm = new Vue({ data: { name: 'lxjwlt' } }); vm.name === vm._data.name; // true
因此咱们要找的数据实际在VueJS实例的_data
属性中。接下来咱们经过getOwnPropertyDescriptor获取数据的getter函数:
Object.getOwnPropertyDescriptor(vm._data, "name").get;
找到了getter函数,咱们就可使用debug接口对其进行断点调试:
debug(Object.getOwnPropertyDescriptor(vm._data, "name").get)
这样,当咱们获取vm.name
数据时,天然会触发该数据的getter函数,从而触发断点调试,自动定位到了函数所在的地方:
往后要调试或者定位公共API,不妨试试Chrome的debug接口功能!
在Chrome中,咱们能够给断点设置表达式,当表达式为true时断点调试才会生效,这就是条件断点。
有了条件断点,咱们在调试代码的时候可以更加精确的控制代码断点的时机,特别是一段代码会被反复运行的时候,条件断点可以跳过大多数状况,只关注咱们想要的情景。除了这一点外,条件断点调试还有另外一个用法。
在断点调试中,咱们每每会检查当前代码的执行状态,若是操做比较繁琐,那么咱们可使用条件断点添加自动化操做,帮助咱们减小一部分工做量。
好比咱们要在断点发生后查看DOM元素,那么断点条件能够这么写:
// 当DOM元素知足某个条件进行断点,同时查看这个元素 elem.hasAttribute('class') && inspect(elem);
若是不清楚操做的返回值,咱们能够强行让该操做返回true,从而不影响断点的条件判断:
elem.hasAttribute('class') && (inspect(elem) || true);
或者分行写:
if (elem.hasAttribute('class')) {inspect(elem); true;}
再好比,在VueJS的调试中,咱们每每须要知道VueJS实例的当前状态,因此每次触发断点调试时,咱们能够先使用clear接口清除控制台历史输出,再将VueJS实例的当前状态打印出来:
vm.sum > 4 && (clear() || vm.$log() || true);
若是在条件断点中定义变量,变量是定义到全局做用域上,即window对象上的
Chrome调试器的Async模式是为调试异步函数所设计一个功能。
在Promise被普遍应用的今天,咱们都知道,Promise的回调是异步执行的,没有开启Async模式前,调动栈只记录到回调函数自己,咱们没法找到代码执行的顺序,这给咱们调试带来巨大的困难。Async模式能够解决这个问题:
开启Async模式后,异步函数以前的调用栈都会被记录下来,并且调用栈中代码执行状态也获得了保留。