本文介绍JavaScript断点与动态调试的基础方法。通过Chrome开发者工具在源码处设置断点,利用F10单步执行和F8继续执行,实时查看变量作用域与闭包。重点讲解异步Ajax回调函数的调试技巧,包括在回调内部设置断点以获取返回数据,验证参数逻辑及错误处理流程。
JavaScript 断点与动态调试概述
前文已介绍JavaScript调试的基础知识,本节由乱码兄弟继续讲解JS断点与动态调试的具体操作方法,供读者参考。
昨天留的课后练习 1. 分析 votePost 函数是如何实现 推荐的。 其实我们已经看到了源码,只要读下源码即可知道他是怎么实现的了。
function votePost(n, t, i) {
i || (i = !1);
var r = {
blogApp: currentBlogApp,
postId: n,
voteType: t,
isAbandoned: i
};
$("#digg_tips").css("color", "red").html("提交中...");
$.ajax({
url: "/mvc/vote/VoteBlogPost.aspx",
type: "post",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(r),
success: function(n) {
if (n.IsSuccess) {
var i = $("#" + t.toLowerCase() + "_count");
r.isAbandoned ? $(i).html(parseInt($(i).html()) - 1) : $(i).html(parseInt($(i).html()) + 1)
}
$("#digg_tips").html(n.Message)
},
error: function(n) {
n.status > 0 && (n.status == 500 ? $("#digg_tips").html("抱歉!发生了错误!麻烦反馈至contact@cnblogs.com") : $("#digg_tips").html(n.responseText))
}
});
}
大致效果如此。注:此处使用 Sublime Text 进行代码格式化,与 Chrome 控制台格式化结果略有差异。也可尝试在线格式化工具 Online JavaScript beautifier,效果相近。
votePost 函数逻辑分析
简要阅读代码后可知,该函数包含三个参数:第一个为 postId(文章ID),第二个为 voteType(推荐 digg 或反对 bury)。第三个参数此前未使用,且默认值为 false。继续向下分析,代码在 #digg_tips 元素处显示“提交中...”字符串,随后通过 Ajax 提交数据至后台。接收返回数据后,若 n.IsSuccess 为真,则在对应的喜欢(#digg_count)或反对(#bury_count)计数元素上数值加 1。但若 isAbandoned 值为真,则计数减 1。据此推测,第三个参数用于撤销推荐或反对操作,即点击推荐后若不想推荐,可传递第三个参数 true 来实现取消。后续将通过测试验证。此外,代码会在 #digg_tips 处显示服务器返回的 n.Message 信息。若 Ajax 发生错误且状态码为 500,则提示“抱歉!发生了错误!麻烦反馈至contact@cnblogs.com”,其他状态码则直接显示服务器返回的错误信息。该函数逻辑简单,基本可直观理解。
部分新手可能疑惑如何知晓 currentBlogApp、n、t、i 的具体值。接下来进行动态调试,这对于编译后的项目调试极为有效。首先定位至 votePost 源码位置(此前已提及,若不清楚可回顾)。
设置断点与查看变量
成功定位到源码。接下来点击第 92 行的行号以设置断点。为何不在第 91 行设置?因为第 91 行仅为函数声明部分,无法在此处断点,需在函数实际执行的代码处设置。
可见第 91 行的行号变为蓝色,表示断点已设置。同时,右侧 Breakpoints 面板中列出了已设置的断点。Breakpoints 面板用于管理所有断点,可方便跳转至对应位置,后续将频繁使用。
设置断点后,点击“推荐”按钮(虽感觉像是在骗推荐,但当初仅随机选取按钮作为练习)。点击后,程序并未执行推荐功能,而是跳转至控制台 Sources 面板中刚设置的断点处。
此时,右侧 Scope Variables(变量作用域)面板显示当前变量,且将鼠标悬停于任意变量上即可查看其值。Scope Variables 栏目会显示当前作用域、父级作用域及闭包信息。这对初学者理解闭包非常有帮助。
单步执行与异步回调调试
接下来,按 F10 键三次,界面显示如下。
每按一次 F10 执行一条语句。按三次后,执行至 $("#digg_tips").css("color", "red").html("提交中..."); 因此页面 #digg_tips 显示“提交中”。然而,再次按 F10 时,程序直接执行完毕,并未进入 Ajax 内部的回调函数。
这是关键问题,也是本节重点。对于此类回调函数,尤其是异步操作,需在回调函数内部再次设置断点。因此,在第 96 行设置断点。再次点击“推荐”,程序仍停在第 92 行,此时直接按 F8 即可在 Ajax 回调函数处中断。
此时可调试回调数据,同时右侧 Scope Variables 中出现 Closure(闭包)项。若暂不理解可跳过,闭包需大篇幅介绍,此处仅知控制台功能强大即可。观察 Ajax 返回数据 n,可见 IsSuccess 属性为 false,未成功,因返回信息为“不能推荐自己的内容”。动态调试使寻找 Bug 变得简单。
验证撤销推荐功能
接下来实验第三个参数。在控制台输入 votePost(cb_entryId, 'Digg', true); 并回车。程序同样停在第 92 行断点处,此处不再逐步调试,直接按 F8 进入 Ajax 回调函数。
在此可清晰看到,当第三个参数为 true 时,确实取消了推荐,且推荐数减 1,即使刷新页面亦保持该状态。
本次使用了两个快捷键 F10 和 F8,明日将详细介绍,今日先掌握基础调试。
课后练习(提高难度): 1. 查看下方评论的“提交评论”按钮,并找到其事件(由 jQuery 绑定)。 2. 动态调试该“提交评论”事件的执行过程。
若无法完成此练习,推荐阅读《浅谈 jQuery 事件源码定位问题》,其中有详细分析。
本文来自:博客园博主 乱码 的文章。http://www.cnblogs.com/52cik/