12月阅读周·编写可测试的JavaScript代码:调试之浏览器内调试篇
背景
去年下半年,我在微信书架里加入了许多技术书籍,各种类别的都有,断断续续的读了一部分。
没有计划的阅读,收效甚微。
新年伊始,我准备尝试一下其他方式,比如阅读周。每月抽出1~2个非连续周,完整阅读一本书籍。
这个“玩法”虽然常见且板正,但是有效,已经坚持阅读十一个月。
已读完书籍:《架构简洁之道》、《深入浅出的Node.js》、《你不知道的JavaScript(上卷)》、《你不知道的JavaScript(中卷)》、《你不知道的JavaScript(下卷)》、《数据结构与算法JavaScript描述》、《WebKit技术内幕》、《前端架构:从入门到微前端》、《秒懂算法:用常识解读数据结构与算法》、《JavaScript权威指南》、《JavaScript异步编程设计快速响应的网络应用》。
当前阅读周书籍:《编写可测试的JavaScript代码》。
浏览器内调试
Firefox
作为调试器的始祖,Firebug是Firefox的一个扩展,在JavaScript调试器里提供了所有的调试技巧。安装最新版本(撰写本文时是版本1.11.1)之后,重启Firefox,选择Tools→Web Developer→Firebug→Open Firebug启动Firebug。Firebug窗口默认会在浏览器底部打开;或者也可以将其从浏览器中“分离”出来,单独一个窗口放在自己喜欢的地方。图7-3显示了正在浏览Yahoo.com时的Firebug窗口。
使用Firebug,可以操作HTML和CSS、单步调试JavaScript,并设置断点。Net面板将显示我们熟悉的元素加载瀑布图。JavaScript加载并被解析之后,我们会看到瀑布图中的差异——Speed Tracer(Chrome中)以及dynaTrace(Windows中)可以解决这些差异。
Firebug还提供了window.console对象,利用该对象可以将消息输出到console控制台。除了打印字符串以外,可以向console的输出方法传入任意对象,Firebug将会解析该对象并显示它的各个字段。可以使用console.time(<字符串>)和console. TimeEnd(<字符串>)方法显示基本的计时信息(是的,字符串要匹配,以便可以同时拥有多个重叠的计时器)。Firebug还将显示两个调用之间所花费的时间。可以使用console.profile()和console.profileEnd()方法查看计时相关的详细信息,Firebug会显示在这两个方法之间所调用的每个函数所花费的详细时间信息。Firebug还提供了console.trace()方法用于生成堆栈跟踪,包括给所有函数传递的所有参数信息。对象可以用console.dir(<对象>)进行查看,而HTML节点可以用console.dirxml(<节点引用>)进行查看。最后,如果条件不为true,console.assert(<布尔条件>)将会在控制器显示一个红色的错误消息。
可以在Firebug中执行任意JavaScript代码,或者在代码里放置console.*语句并进行跟踪,也可以在代码里插入一个debugger语句进行断点设置,但是要注意,在完成调试之后要把它删除!
最后,Firebug可以使用displayName属性对匿名函数进行命名。用示例演示一下就很容易理解。想象一下要调试如下函数:
function getIterator(countBy, startAt, upTill) {
countBy = countBy || 1;
startAt = startAt || 0;
upTill = upTill || 100;
var current = startAt;
return function () {
current += countBy;
return current > upTill ? NaN : current;
};
}
上述示例中的简单函数创建了一个迭代器。如下代码是它的用法:
var q = getIterator(1, 0, 200);
console.log(q());
代码很简单,但在Firebug里进行调试并查看堆栈时。
该堆栈将该函数的名称显示为(?)。Firebug不知道该匿名函数的名称叫什么,所以可以使用匿名函数的displayName属性告诉堆栈它叫什么名称,示例如下:
function getIterator(countBy, startAt, upTill) {
countBy = countBy || 1;
startAt = startAt || 0;
upTill = upTill || 100;
var current = startAt;
var ret = function () {
current += countBy;
return current > upTill ? NaN : current;
};
ret.displayName = 'Iterator from ' + startAt + ' until ' + upTill + ' by ' + countBy;
return ret;
}
在这里,我给匿名函数添加了displayName属性——displayName的描述性文字!
这样好多了!我们将(?)变成了非常有描述性且很有用的东西。可以将displayName属性添加到任意函数(也可以是我们喜欢的任何东西)上。很显然,该属性对匿名函数特别有用,例如通常会在事件回调中使用的匿名函数,或者我们自己生成的匿名函数。
Chrome
Chrome也有一个同样有用的开发工具集(https://code.google.com/chrome/devtools/),包括调试器。从View→Developer菜单可以访问这些工具,Chrome Developer Tools也可以依附在Chrome主窗口的底部,或分离为一个单独的窗口。
Chrome调试器还支持所有Firebug的console方法,并且该调试器也可以对压缩代码进行一个良好的呈现,增加JavaScript代码的可读性。一旦代码经过格式化,我们也可以像平时一样设置断点——非常方便的功能!混淆代码和压缩代码,则需要更多的工作来格式化,本章稍后,我们将研究如何使用源映像(source map)做该项工作。
Chrome调试器还支持对eval块进行“命名”。如果不使用eval,对你就没什么影响。然而,有一些工具——尤其是操作JavaScript的工具,如CoffeeScript编译器——会大量使用eval。
在获取网页时,Chrome还允许我们轻松地更改所发送的User Agent字符串。可以在Settings菜单里访问该功能,在此可以模拟我们想要的任何浏览器。
Safari
和Chrome一样,Safari也是基于WebKit的,其调试器和Chrome调试器非常类似。要使用该工具,首先需要启用Safari里的Develop菜单。启用该菜单的复选框隐藏在Preferences→Advanced→“Show Develop menu in menu bar”下。
现在,我们就拥有了带有很多选项的顶级Develop菜单了。继续打开Web Inspector。
Chrome添加了一些标准WebKit不支持的附属功能——例如,远程调试的JSON协议(尽管其移植到WebKit中了,但该功能在Safari中还不能使用)以及其他一些高级选择——但通常Safari和Chrome几乎可以以同样的方式来呈现页面,所以无论选择哪一个都可以。当然,两个浏览器之间还是有一些差异,但它们之间的差异不像Safari/Chrome和Firefox那么明显,尤其是Safari/Chrome和Internet Explorer之间。像Chrome一样,Safari也可以很方便地修改要发送的User Agent字符串,从而伪装成不同的浏览器进行发送。还可以向网站输入一个任意字符,以便优化向其他浏览器发送的内容。这对于假装成移动iOS浏览器非常有用,因为iPhone、iPad和iTouch的User Agent字符串也是可用的。图7-13展示了选择iPhone User Agent字符之后,接着访问LinkedIn时的效果。
Internet Explorer
对于还没有提到的Internet Explorer,我在此不做过多叙述。可惜的是,大多数用户可能都在使用IE。幸运的是,IE 8和早期版本的使用正在减少;而且IE 8和后续版本还提供一个很好的调试器(https://msdn.microsoft.com/en-us/library/ hh772704(v=vs.85).aspx)。在键盘上按F12键可以访问IE调试器(因此得名“F12 Developer Tools”),或通过工具(Tools)菜单访问。该调试器提供了与Firefox、Webkit浏览器类似的工具,包括基本的分析信息。
IE 8还提供console对象,但功能非常有限:只支持log、info、warn、error和assert。
总结
调试客户端JavaScript就一定会利用各浏览器本身提供的调试器或浏览器上的扩展。在StateCounter网站上,可以查看当前每个浏览器在全球或我们所在地区的市场份额。
当然,Web服务器日志可以为应用程序提供最准确的浏览器使用情况评估,但根据如图7-1所示的全球统计数据来看,在所有其他浏览器市场份额都在下降或停滞不前的情况下,Google Chrome的市场份额却一路飙升。针对特定的浏览器版本,截至2012年10月的数据,使用Chrome 17和IE 9.0的份额在上升,而只占有15%市场份额的其他主要浏览器版本的份额却在下降。
作者介绍
非职业「传道授业解惑」的开发者叶一一。
《趣学前端》、《CSS畅想》等系列作者。华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。
如果看完文章有所收获,欢迎点赞👍 | 收藏⭐️ | 留言📝。
- 点赞
- 收藏
- 关注作者
评论(0)