12月阅读周·编写可测试的JavaScript代码:调试之浏览器内调试篇

举报
叶一一 发表于 2024/12/23 18:11:52 2024/12/23
【摘要】 背景去年下半年,我在微信书架里加入了许多技术书籍,各种类别的都有,断断续续的读了一部分。没有计划的阅读,收效甚微。新年伊始,我准备尝试一下其他方式,比如阅读周。每月抽出1~2个非连续周,完整阅读一本书籍。这个“玩法”虽然常见且板正,但是有效,已经坚持阅读十一个月。已读完书籍:《架构简洁之道》、《深入浅出的Node.js》、《你不知道的JavaScript(上卷)》、《你不知道的JavaScr...

背景

去年下半年,我在微信书架里加入了许多技术书籍,各种类别的都有,断断续续的读了一部分。

没有计划的阅读,收效甚微。

新年伊始,我准备尝试一下其他方式,比如阅读周。每月抽出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畅想》等系列作者。华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。
如果看完文章有所收获,欢迎点赞👍 | 收藏️ | 留言📝

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。