Javascript高级调试(上)

作者:Chris Mills,Hallvord R. M. Steen 来源:alistapart.com 时间:2009年1月3日  翻译Shellway
原文地址:http://www.alistapart.com/articles/advanceddebuggingwithjavascript
原文版权归原作者及原网站所有,*转载请保留以上文字!

[singlepic id=40 w=320 h=240 mode=watermark float=center]

当有效地使用的时候,JavaScript调试器能帮忙找出和处理你的JavaScript代码中的错误。要想成为一名高级JavaScript调试员,你需要知道你可用到的一些调试器,典型的JavaScript调试工作流程,还有高效调试的核心条件。在本文中,我们将讨论高级调试技术,使用一个简单的Web应用来诊断和处理bug。

>>关于可及性(accessibility)

本文重点描述了各调试工具的优势和之间的区别,展示了我们如何执行高级JavaScript调试任务。我们的方法通常依赖于鼠标,如果你更喜欢使用快捷键,或者你是依赖于如屏幕阅读器等辅助技术来与这些工具互动的,那你应该参考相关文档,以决定如何(是否)这些工具会运行。

>>调试器

随着优秀的调试器不断增加,JavaScript程序员可以从学习如何使用它们而收获良多。JavaScript调试器的用户界面正变得越来越精美,产品之间更标准化,以及更易用。这些使专家和菜鸟们都更容易学习JavaScript调试。

目前,所有主流浏览器都有可利用的调试工具:
-Firefox拥有一个著名的Firebug扩展;
-IE8(本文写作时还是Beta版)则自带了开发者工具;
-Opera(V9.5及更高)支持Opera Dragonfly(蜻蜓)调试器;
-Safari有Drosera Js调试器和被称作WebInspector的DOM查看器。更多近来版本的Safari中,调试器已经被整合到WebInspector中了。

目前,Firebug和Dragonfly是其中最稳定的。IE8的beta工具有时会忽略断点,并且在写作本书时,WebInspector看起来与Webkit的构造存在兼容性问题。

熟悉多种调试工具吧,因为你不知道下一个bug会在哪个浏览器中出现。既然调试器之间的功能只有粗略差异,那一旦知道如何使用一个,你就很容易换用调试器。

调试工作流程

当调查一个特定问题是,你通常将遵循以下过程:
1. 在调试器的代码查看窗口找出相关代码;
2. 在你觉得将发生有趣的事的地方设置断点;
3. 若是行内脚本,则在浏览器中重载页面,若是一个事件处理器则点击按钮,以再次运行脚本;
4. 一直等到调试器暂停执行并通过代码;
5. 查看变量值。比如,看看那些本该包含一个值却显示未定义的变量,或者当你希望他们返回“true”却返回“false”时;
6. 如果需要,使用命令行对代码进行求值,或者为测试改变变量;
7. 通过学习导致错误情况发生的那段代码或输入,来找出问题所在。

你也可以添加声明调试器到你的代码中,来创建一个断点:
function frmSubmit(event){ event = event || window.event; debugger; var form = this; }

调试器需求

多数调试器需要格式良好的代码。在行列调试器中,写在一行中的代码使其难以发现错误。迷乱的代码很难调试,尤其是那些被“packed”过,需要用eval()解包的。许多JavaScript库允许你在打包的/迷乱的和格式良好的版本中选择,使它容易使用格式化的代码来调试。

调试示例

让我们先以一个小的充满错误的例子开始,以逐一了解如何诊断和修复毛病。我们的例子是一个Web应用程序登录屏幕。

假设您正在处理这一惊人的新Web应用程序,您的测试者要求您调查这个错误的清单:

1、“正在加载… ”状态栏的信息在完成加载后仍不消失;

2、在英语版的Firefox和IE浏览器,语言都默认是挪威语;

3、一个名为“prop”的全局变量被创建于某处;

4、在DOM查看器,所有的内容均有一个“克隆”(clone)属性;

5、“最小长度”的表单验证不能正常工作,试图提交只有一个字母的用户名的表单本该引发一条错误信息的。

6、允许密码字段留空——在提交表单是,你本应该看到一条错误消息,提示“密码字段不能为空”;

7、登录总是失败,错误信息提示:检测到一个跨站点请求伪造攻击。

启动调试器

◎在Firefox浏览器中,你需要确认已安装的Firebug扩展。选择“工具 > Firebug > 打开Firebug”即可开始;
◎在Opera 9.5测试版2或更高版本中,请选择“工具 > 高级“开发工具”;
◎在IE8测试版中,选择“工具 > 开发工具”;
◎在Safari或WebKit中,先启用调试菜单,然后选择“调试 > 显示Web Inspector”。

现在是时候了开启调试器了。密切注意文章剩余部分的步骤,跟着演示。由于一些指示涉及修改代码,您可能需要保存网页到本地,并在开始之前从您的文件系统加载。

Bug 1:在状态栏中的“正在加载… ”消息
如果你在Dragonfly和Firebug看一下正调试的应用,你将看到一个如图1那样的画面:

[singlepic id=41 w=320 h=240 mode=watermark float=center]

[singlepic id=42 w=320 h=240 mode=watermark float=center]

图1:起初在Dragonfly和Firebug中看到的JavaScript。

在你查看调试器的源代码时,请注意,代码顶部定义有一个函数clearLoadingMessage()。这似乎是一个设置断点设置好地方。

以下是做法:
1、单击左边的行号,在函数clearLoadingMessage()内的第一行设置断点;
2、重新加载网页。

注:断点必须建立在函数运行时将执行的代码行上。包含函数clearLoadingMessage()的行只是函数标识符。在此处设置断点永远不会真正使调试器在此处停止。相反地,请在函数内第一行设置断点。
网页重载时,脚本的执行将停在断点,你将看到一个如图2一样的输出。(Dragonfly显示在顶部,Firebug则在底部。)

[singlepic id=43 w=320 h=240 mode=watermark float=center]

[singlepic id=44 w=320 h=240 mode=watermark float=center]

图2:在clearLoadingMessage函数中,调试器停止在断点上了。

我们往下看。您会看见更新了两个DOM元素,并在28行上提到“statusbar”这个词。这貌似很要紧。很有可能是,getElements(‘P’, {‘class’:’statusbar’})[0]将在DOM中找到“statusbar”元素。你有办法快速测试这一原理吗?

将有关片段粘贴到命令行来检查您的理论。图3显示了三个截图(Dragonfly,Firebug以及IE8)在读取了元素的innerHTML或outerHTML后,你输入的命令返回的。

为了检验这一假设,请:
1、找到的命令行:
在Firebug中,切换到“控制台”标签;
在Dragonfly中,查看JavaScript源代码窗格下面;
在IE8开发工具中,在标示为“控制台”找到正确的标签;
2、粘贴getElements( ‘p’, {‘class’:’statusbar’} )[0].innerHTML到命令行;
3、按ENTER键。

[singlepic id=45 w=320 h=240 mode=watermark float=center]

[singlepic id=46 w=320 h=240 mode=watermark float=center]

[singlepic id=47 w=320 h=240 mode=watermark float=center]

图3:分别在Dragonfly,Firebug和IE8下显示的输出