常用快捷键
ctrl+p 项目中定位文件,以下查找 VueJS 库文件:
ctrl+shif+o 文件中定位成员函数,以下定位到 VueJS 的 nextTick 接口:
Snippets 随时编写代码
Chrome 在 souces 页面提供 snippets 一栏,这里我们可以随时编写 JS 代码,运行结果会打印到控制台。代码是全局保存的,我们在任何页面,包括新建标签页,都可以查看或运行这些代码。
我们不再需要为了运行一小段 JS 代码而新建一个 HTML 页面。snippets 的方便之处在于,你只需要打开 chrome 就可以编写一份任意页面都可以运行的 JS 代码,而且用过 snippets 都知道,snippets 编辑器是可以和 sublime text 相媲美的。
某次项目中,我需要将 100 多页的 word 文档导入到页面中。考虑后续样式编写,页面的 HTML 结构如下:
<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 包装。
由于不需要视图的支持,在 snippets 编写这段代码是最好的选择,经过几次调试修改,最终成果如下:
最后,将 Word 文档内容复制到 snippets 中,执行解析函数,最终的解析出来的 HTML 结果打印到控制台:
snippets 中可以使用控制台的 copy 接口,解析结果直接拷贝到剪切板会更方便
使用 snippets 来完成这类轻量级工作时,不需要追求代码的可读性、可维护性,我们的代码只需要在大部分场景下能够正常运行就足够了。
但为了满足大部分场景,代码也是需要反复调试修改。snippets 最实用之处恰恰在于,随时编写,随时调试,随时修改!
copy 格式化拷贝
在项目开发中,我们可能需要将后台数据拷贝到本地,作为本地数据进行调试。
如果后台返回没有格式化的 JSON 数据,在本地调试中我们难免会遇到手动修改数据的情况,格式不美观的 JSON 数据修改起来会异常困难。
说到 JSON 的格式化,我们首先想到的是 JSON.stringify 的格式化功能,例如四个空格的缩进:
JSON.stringify({name: 'lxjwlt'}, null, 4);
每次格式化 JSON 数据都要编写这段代码实在太麻烦,我们可以使用 chrome 控制台的 copy 接口解决这一问题:
- 请求项的右键菜单中选择 Copy Response 拷贝响应内容
- 命令行中使用 copy 接口处理数据
- 得到格式化的 JSON 数据
不仅仅是对象,copy 接口对任何数据都可以进行拷贝,这里利用的是 copy 在拷贝数组或对象过程中,对数据进行美化的功能
iframe 调试
如果我们使用 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 进行调试,你会感谢这个功能。
debug 毫无用处?
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 接口功能!
条件 breakpoint
在 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 对象上的
Async 调试
Chrome 调试器的 Async 模式是为调试异步函数所设计一个功能。
在 Promise 被广泛应用的今天,我们都知道,Promise 的回调是异步执行的,没有开启 Async 模式前,调动栈只记录到回调函数本身,我们无法找到代码执行的顺序,这给我们调试带来巨大的困难。Async 模式可以解决这个问题:
开启 Async 模式后,异步函数之前的调用栈都会被记录下来,而且调用栈中代码执行状态也得到了保留。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于