掌握JavaScript:新手到专家的忍者之路

发表时间: 2020-05-20 17:37

你应该已经知道,没有什么简单方法可以创建有效且跨浏览器的JavaScript 代码,除了编写整洁代码的常规挑战外,我们还要额外应对各种浏览器的差异和复杂性。为了应对这些挑战,JavaScript开发人员通常使用JavaScript库来实现通用和可重用的功能。

这些库虽然在方法、内容和复杂性方面有很大差异,但唯一不变的是:它们都需要简单易用,产生最少的开销,并能兼容所有浏览器,这些都是我们所希望的。

1. 即将探索的JavaScript库

创建现代JavaScript库所用到的技术和实践是我们所关注的焦点。我们要选择一个最重要的库,当然就是jQuery,其已经跃升为目前最普遍使用的JavaScript库了。

jQuery(http://jquery.com)由John Resig创建,并在2006年1月发布。jQuery将用于匹配DOM内容的CSS选择器进行了普及。在众多功能中,它还提供了DOM操作、Ajax、事件处理以及动画功能。

jQuery已经主导了JavaScript库的市场,它被用于成千上万的网站,数以百万计的用户与之交互。通过大量的使用和反馈,该库一直在精练——继续优化——成为目前我们正在使用的最优代码。

除了研究jQuery示例代码以外,我们也会了解以下库所利用的技术。

※Prototype(http://prototypejs.org/)——现代JavaScript库之父,Sam Stephenson于2005年创建并发布。除了面向对象编程、面向切面编程以及函数式编程技术以外,该库还包含了DOM、Ajax和事件功能。

※Yahoo!UI(
http://developer.yahoo.com/yui)——雅虎内部JavaScript框架发展的结果,在2006年2月向公众发布。除了一些预先定义的部件(日历、网格、手风琴等)以外,Yahoo !UI(YUI)还包括DOM、Ajax、事件以及动画功能。

※base2(
http://code.google.com/p/base2)——由Dean Edwards创建,于2007年3月发布。该库支持DOM和事件功能。它的闻名之处在于它尝试以通用且跨浏览器的方式实现各种W3C规范。

这些库都经过了全面的构建并且解决了目标问题。基于这些原因,这些库对于我们进一步分析并理解代码库的基础建设,从而洞察世界级JavaScript库建设的过程打下了良好的基础。

但是这些技术,并不只用于构建大型库;它们也可以应用于所有的JavaScript代码,且无论代码大小。

一个JavaScript库的组成可以分为如下三个方面。

※ JavaScript语言的高级使用。

※ 跨浏览器代码的精心构建。

※ 当前能够聚众合一的最佳实践应用。

针对每个库,我们会仔细分析这三个方面,从而收集整理完整的知识体系,以便创建自己的高效JavaScript代码。

2. 理解JavaScript语言

很多JavaScript程序员,在工作中不断进步,直到能够熟练使用大量的JavaScript语言元素,包括对象、函数(如果他们始终关注编码趋势)甚至是匿名内联函数。然而,在许多情况下,这些技巧可能并没有超出基础水平。此外,这些程序员,通常对JavaScript中闭包(closures)的目的和实现有着非常匮乏的理解,而闭包从根本上例证了函数对于该语言的重要性。

JavaScript中,对象、函数和闭包之间有着很密切的关系(如图1.1所示)。理解这三个概念之间的牢固关系,可以大大提高我们的JavaScript编程能力,为我们进行任意类型程序的开发打下坚实的基础。


图1.1 JavaScript中,对象、函数和闭包之间的密切关系

很多JavaScript开发人员,尤其是有面向对象背景的开发人员,可能会更多地关注对象,但却没有了解函数和闭包对于整个程序的作用。

除了这些基本概念,还有两个JavaScript特性远远未被充分利用:定时器和正则表达式。这两个概念,几乎在任何程序的JavaScript代码中都有,但由于易于被误解,因此它们并没有发挥全部潜力。

熟练掌握定时器如何在浏览器内运行(通常很神秘的),可以让我们有能力解决复杂的编码任务,如长时间运行的计算和平滑的动画。而理解正则表达式是如何工作的,可以让我们简化原本相当复杂的代码段。

作为JavaScript语言之旅的另一个高潮,我们将研究第10章中的with语句,以及第9章中有争议的eval()方法——两个重要但是具有争议的语言特性,这两个特性已经被滥用、误用,甚至有很多JavaScript程序员对其怨声载道。

注意:

持续关注Web开发技术发展趋势的人会知道这两个主题是有争议的,在未来版本的JavaScript中会被弃用或者被限制使用。但由于在现有代码中可能会遇到这些概念,所以即使在将来的代码中不使用它们,理解它们也是非常重要的。

观察一些高级JavaScript程序员的工作,我们将会看到,恰当使用一些高级语言特性可以创建一些神奇的代码片段,而其他方式则往往不太可能。在很大程度上,这些高级特性也可以用于一些有趣的元编程练习,将JavaScript代码编写成任意我们想要的。

学习如何高效使用高级语言特性,以及如何发挥其最大优势,将代码质量提升到更高的水平。提升我们运用这些概念和特性的能力,提高我们的理解力,熟练掌握如何创建任意类型的JavaScript应用程序。这些基础知识,将为我们开始编写稳定跨浏览器代码的道路奠定坚实的基础。

3. 跨浏览器注意事项

完善JavaScript编程技能将引导我们不断前行,尤其是目前,除了浏览器端以外,JavaScript还能够使用Rhino、V8或Node.js库等JavaScript引擎在服务器端运行。但开发基于浏览器的JavaScript应用程序时,越早越好的是,我们首先要应对:浏览器及其令人恼火的问题和矛盾。

理想世界中,所有的浏览器中都没有bug,并且支持以一致的方式支持Web标准,但是我们都知道我们并不生活在这种世界里。

近来浏览器的质量已经有了大大改善,但仍有一些bug、缺失的API和不同浏览器的特定缺陷,我们需要解决这些问题。制定解决这些浏览器问题的综合性策略并熟悉不同浏览器之间的区别和缺陷,和精通JavaScript本身同等重要。

对于这些差异,在编写浏览器应用程序或JavaScript库时,决定支持哪些浏览器是一个重要考虑事项。我们可能想支持所有的浏览器,但却受限于开发和测试的资源限制。那么,我们如何决定支持哪些浏览器,支持到什么程度?

有一个方法,是来自古老Yahoo!的一个松耦合方式,称为分级浏览器支持(graded browser support)。在这种技术中,我们创建一个浏览器支持矩阵,作为记录浏览器和其平台的重要性的快照。

在这样一个表格中,我们在一个轴上列出目标平台,在另外一个轴上列出浏览器。然后,在每个单元格中,对每个浏览器/平台组合,我们给出一个“等级”(从A到F,或者是其他能够满足我们需要的评分系统)。

注意,我们还没有填写任何等级。如何对特定平台和浏览器分配等级,完全取决于项目的需要和需求,以及其他重要的因素,例如目标受众的组成。使用这种方式,我们制定出相应平台/浏览器重要性的等级,并将这些信息和成本进行结合,尝试找出最优化的浏览器支持。我们将在第11章更深入地探索这些内容。

由于支持大部分的平台和浏览器组合是不切实际的,因此我们必须权衡支持各种浏览器的成本与收益。任何类似的分析,都必须要考虑多个因素,主要有如下几点。

※目标受众的期望和需求。 ※浏览器的市场份额。 ※览器所需的工作量。

第一点是主观的,只有具体项目才能够确定。第二点是市场份额,可以通过互联网信息得到。支持每个浏览器的工作量,可以通过考虑该浏览器的功能和对现代浏览器标准的遵守情况进行粗略估计。

图1.2所示的图表,展示了主流浏览器的使用情况(信息来自2012年8月的StatCounter)以及我们对排名靠前的桌面浏览器开发成本的个人建议。


图1.2 各种桌面浏览器的支持成本与收益分析,揭示了我们要努力的方向

图表以“收益”与“成本”的方式进行展示,大概一看就可以知道怎么做“最划算”。跳出该图表,如下还有几点要注意的事项。

尽管与标准兼容的浏览器相比,支持IE 7和IE 8需要更多的工作量,但它们仍然有很大的市场份额,如果这些用户是我们程序的一个重要目标观众,那么这些额外的工作就是值得的。

IE 9,在标准兼容性方面取得明显进展,与之前的IE版本相比更容易得到支持,并已经取得了一定的市场份额。

支持Firefox和Chrome是显而易见的,因为它们有很大的市场份额,并且很容易支持。

尽管Safari浏览器的市场份额相对较低,它仍然值得支持,因为它符合标准的特性使得其支持成本很小(作为一个经验法则,如果能在Chrome浏览器下使用,那也就能在Safari下使用——尽管是在推理情况下)。

Opera,虽然需要的工作量比Safari还少,但因为它的市场份额很小,所以可以从桌面浏览器市场上忽略它。但如果移动平台对你来说很重要,移动版的Opera则可以发挥更大的作用,如图1.3所示。

图1.3 移动市场,开发成本和收益相当,实际源于统计数据

对于IE 6,真的没什么可说的了。(参见www.ie6countdown.com。)

看一下移动市场,情况就完全不同了,如图1.3所示。

当然,任何事情都不是那么枯燥。也许更恰当的说法是,好处比成本更重要,但这最终要看决策者的选择,他们要考虑市场需求和其他业务问题等因素来制定决策。但量化成本和收益是做出这些重要支持决策的一个良好起点。

另外,要注意,市场份额和支持成本的变化是很迅速的。密切关注像http://gs.statcounter.com这样的网站不失为一个明智的预防措施。

资源受限组织的另一个潜在因素是开发团队的技能。开发应用程序的主要原因就是让最终用户使用,开发人员可能需要发展必要的技能来开发该应用程序,以满足最终用户的需求。在成本分析阶段就需要考虑这些因素。

跨浏览器开发的成本,主要取决于开发人员的技能和经验,所以让我们首先来看一下当前的最佳实践。

4. 当前最佳实践

掌握JavaScript语言和跨浏览器编码问题是成为Web应用程序开发专家的重要条件,但它们并不是全部。要进军专家行列,还需要秀出以下很多开发人员之前都已经掌握的高质量代码。我们将在第2章深入研究这些被称为最佳实践(best practices)的特征,除了熟练掌握语言外,还包括如下元素。

※ 测试。

※ 性能分析。

※ 调试技巧。

在我们的编程过程中,时常遵守这些最佳实践是极其重要的;跨浏览器开发的复杂性也直接证明了这一点。让我们来看看这些实践。

4.1 当前最佳实践:测试

我们将使用大量的测试技术,以确保示例代码的运行符合我们的预期,同样也作为测试一般代码的示例。对于测试,我们将使用的一个主要工具是assert()函数,其目的是断言代码是true还是false。

该函数的一般形式是:

第一个参数是一个条件,应该是true,而第二个参数则是一个消息,在第一个参数不为true时进行显示。

考虑如下代码:

如果变量a的值不等于1,断言就会失败,这些过于戏剧性的消息就会显示。

注意,assert()函数并不是JavaScript语言的原生特性(一些像Java这样的语言,也提供这样的功能),所以我们会自己实现它。我们将在第2章讨论assert()函数的实现以及使用。

4.2 当前最佳实践:性能分析

另一个重要的实践是性能分析。浏览器的JavaScript引擎在JavaScript本身的性能表现上取得了惊人的进步,但这并不是我们编写劣质和低效代码的借口。

我们将使用的如下代码,收集性能信息:

上述代码中,我们在代码执行的地方记录时间戳:一个在代码执行开始前,一个在代码执行后。两个时间戳之间的差值告诉我们代码执行了多少时间,使用相同的方式,我们可以测量其他替代代码方案的执行时间。

注意我们是如何多次执行代码的;在本例中,我们执行的次数由maxCount表示。因为代码的单次操作执行太快而很难准确地测量,所以我们需要多次执行代码以获取可衡量的值。至于执行次数有多频繁,这个数可以是成千上万,甚至上百万,这取决于被测代码的性质。通过反复试验,我们可以选择一个合理的值。

这些最佳实践技术,以及在这个过程中我们将学到的其他实践,将极大地提高我们的JavaScript开发水平。用浏览器提供的有限资源开发应用程序,再加上浏览器功能和兼容性问题的日益复杂,因此掌握完整和强大的技能是非常必要的。

5. 总结

以下是我们在本文所学到的内容。

跨浏览器的Web应用程序开发是困难的,比大多数人想象的都要难。 为了圆满完成跨浏览器开发,我们不仅要掌握JavaScript语言,还要全面了解浏览器以及它们的怪异模式和矛盾,并要具备当前最佳实践方面的良好基础。 JavaScript开发毋庸置疑是很具有挑战性的,但有一些勇敢者已经沿着这条曲折的道路走了下来,那就是JavaScript库的开发者。我们将提炼这些代码库中的知识,有效地提高我们的开发技能,并将这些技能提升到世界一流水平。

这些探索肯定会很有益且具有教育意义——让我们来享受这个过程吧!

本文节选自《JavaScript忍者秘籍》。



JavaScript语言非常重要,相关的技术图书也很多,但没有任何一本书对JavaScript语言的重要部分(函数、闭包和原型)进行深入、全面的介绍,也没有任何一本书讲述跨浏览器代码的编写。本书是jQuery库创始人编写的一本深入剖析JavaScript语言的书。

本书共分四个部分,从准入训练、见习训练、忍者训练和火影训练四个层次讲述了逐步成为JavaScript高手的全过程。全书从高级Web应用程序开发者所面临的挑战谈起,由浅入深地覆盖了测试和测试工具、函数、闭包、对象、正则表达式、定时器、运行时代码求值、with语句、跨浏览器问题、元素的特性和属性、事件处理、DOM以及CSS选择器等众多核心话题;将严谨的理论讲解和实用的代码示例相结合,引导读者更加深入地了解JavaScript的神奇,充分展示了JavaScript语言的各种特性。

本书适合具备一定的JavaScript基础知识的读者阅读,也适合从事程序设计工作并想要深入探索JavaScript语言的读者阅读。


专栏
Spring Boot 2 核心技术实战基础
作者:异步社区
33.9币
24人已购
查看