当我还是一个初出茅庐的程序员时,我想掌握自己所用语言的每个特性。我写程序时会尝试使用所有的特性。我认为这是炫耀的好方法,而我也的确出了不少风头,因为我对各个特性了如指掌,谁有问题我都能解答。
最终,我认定这些特性中有一部分特性带来的麻烦远远超出它们的价值。其中,一些特性因为规范很不完善而可能导致可移植性问题,一些特性会导致代码难以阅读或修改,一些特性诱使我追求奇技淫巧但却易于出错,还有一些特性就是设计错误。有时候语言的设计者也会犯错。
大多数编程语言都有精华和糟粕。我发现如果取其精华而弃其糟粕的话,我可以成为一个更好的程序员。毕竟,用坏材料怎么能做出好东西呢?
标准委员会想要移除一门语言中的缺陷部分,这几乎是不可能的,因为这样做会损害所有依赖于那些糟粕的蹩脚的程序。除了在已存在的一大堆缺陷上堆积更多的特性,他们通常无能为力。而且新旧特性并不总是能和谐共处,从而可能产生出更多的糟粕。
但是,你有权力定义你自己的子集。你完全可以基于精华的那部分去编写更好的程序。
JavaScript 中糟粕的比重超出了预料。它一诞生,就在短到令人吃惊的时间里被全世界所接受。它从来没有在实验室里被试用和打磨。当它还非常粗糙时,它就被直接集成到网景的Navigator 2 浏览器中。随着 Java™的小应用程序(Java™ applets)的失败,JavaScript 变成了默认的“Web 语言”。作为一门编程语言,JavaScript 的流行几乎完全不受它的质量的影响。
好在 JavaScript有一些非常精华的部分。在 JavaScript 中,美丽的、优雅的、富有表现力的语言特性就像一堆珍珠和鱼目混杂在一起。JavaScript 最本质的部分被深深地隐藏着,以至于多年来对它的主流观点是:JavaScript 就是一个丑陋的、没用的玩具。本书的目的就是要揭示 JavaScript 中的精华,让大家知道它是一门杰出的动态编程语言。JavaScript 就像一块大理石,我要剥落那些不好的特性直到这门语言的真实本质自我显露出来。我相信我精雕细琢出来的优雅子集大大地优于这门语言的整体,它更可靠、更易读、更易于维护。
这本书不打算全面描述这门语言。反之,它将专注在精华部分,同时会偶尔警告要去避免糟粕部分。这里将被描述的子集可以用来构造可靠的、易读的程序,无论规模大小。通过仅专注于精华部分,我们就可以缩短学习时间,增强健壮性,并且还能拯救一些树木
或许,只学习精华的最大好处就是你可以不必头痛如何忘记糟粕。忘掉不好的模式是非常困难的。这是一个非常痛苦的工作,我们中的大多数人都会很不愿意面对。有时候,制定语言的子集是为了让学生更好地学习。但在这里,我制定的 JavaScript 子集是为了让专业人员更好地工作。
为什么要使用JavaScript
JavaScript 是一门重要的语言,因为它是 Web 浏览器的语言。它与浏览器的结合使它成为世界上最流行的编程语言之一。同时,它也是世界上最被轻视的编程语言之一。浏览器的 API和文档对象模型(DOM)相当糟糕,连累 JavaScript 遭到不公平的指责。在任何语言中处理 DOM 都是一件痛苦的事情,它的规范制定得很拙劣并且实现互不一致。本书很少涉及DOM,我认为写一本关于 DOM 的精华的书就像执行一项不可能完成的任务。
JavaScript 是 最 被 轻 视 的 语 言 , 因 为 它 不 是 所 谓 的 主 流 语 言 ( SOME OTHER LANGUAGE)。如果你擅长某些主流语言,但却在一个只支持 JavaScript 的环境中编程,那么被迫使用 JavaScript 的确是相当令人厌烦的。在这种情形下,大多数人觉得没必要先去学好 JavaScript,但结果他们会惊讶地发现,JavaScript 跟他们宁愿使用的主流语言有很大不同,而且这些不同至为关键。
JavaScript 令人惊异的事情是,在对这门语言没有太多了解,甚至对编程都没有太多了解的情况下,你也能用它来完成工作。它是一门拥有极强表达能力的语言。当你知道要做什么时,它还能表现得更好。编程是很困难的事情。绝不应该在懵懵懂懂的状态下开始你的工作。
分析 JavaScript
JavaScript 建立在一些非常优秀的想法和少数非常糟糕的想法之上。
那些优秀的想法包括函数、弱类型、动态对象和富有表现力的对象字面量表示法。那些糟糕的想法包括基于全局变量的编程模型。
JavaScript 的函数是(主要)基于词法作用域(lexical scoping)的顶级对象。JavaScript
是第一个成为主流的Lambda语言。实际上,相对于Java而言,JavaScript 与Lisp和Scheme有更多的共同点。它是披着C 外衣的Lisp。这使得JavaScript 成为一个非常强大的语言。
现今大部分编程语言中都流行要求强类型。其原理在于强类型允许编译器在编译时检测错误。我们能越早检测和修复错误,付出的代价就越小。JavaScript 是一门弱类型的语言,所以JavaScript 编译器不能检测出类型错误。这可能让从强类型语言转向 JavaScript 的开发人员感到恐慌。但事实证明,强类型并不会让你的测试工作变得轻松。而且我在工作中发现,强类型检查找到的错误并不是令我头痛的错误。另一方面,我发现弱类型是自由的。我无须建立复杂的类层次,我永远不用做强制造型,也不用疲于应付类型系统以得到想要的行为。
JavaScript 有非常强大的对象字面量表示法。通过列出对象的组成部分,它们就能简单地被创建出来。这种表示法是 JSON 的灵感来源,它现在已经成为流行的数据交换格式
原型继承是 JavaScript中一个有争议的特性。JavaScript 有一个无类型的(class-free)对象系统,在这个系统中,对象直接从其他对象继承属性。这真的很强大,但是对那些被训练使用类去创建对象的程序员们来说,原型继承是一个陌生的概念。如果你尝试对 JavaScript直接应用基于类的设计模式,你将会遭受挫折。但是,如果你学会了自如地使用 JavaScript原型,你的努力将会有所回报。
JavaScript 在关键思想的选择上饱受非议。虽然在大多数情况下,这些选择是合适的。但是有一个选择相当糟糕:JavaScript 依赖于全局变量来进行连接。所有编译单元的所有顶级变量被撮合到一个被称为全局对象(the global object)的公共命名空间中。这是一件糟糕的事情,因为全局变量是魔鬼,但它们在 JavaScript 中却是基础。幸好,我们接下来会看到,JavaScript 也给我们提供了缓解这个问题的处理方法。
在某些情况下,我们可能无法忽略糟粕,还有一些毒瘤难以避免,当涉及这些部分时,我会将它们指出来。它们也被总结在附录 A 中。但是我们将成功地避免本书中提到的大多数糟粕,它们中的大部分被总结在附录 B 中。如果你想学习那些糟粕,以及如何拙劣地使用 它们,请参阅任何其他的JavaScript 书籍。
《ECMAScript 编程语言》第 3 版定义了JavaScript(又称 JScript)的标准,它可以从http://www.ecma-international.org/publications/files/ecma-st/ECMA-262.pdf获 得 。
本书所描述的是ECMAScript的一个特定的子集。本书并不描述整个语言,因为它排除了糟粕的部分。这里排除得也许并不彻底,回避了一些极端情况。你也应该这样,走极端只会带来风险和苦恼。
附录 C 描述了一个叫 JSLint的编程工具,它是一个 JavaScript 解析器,它能分析 JavaScript问题并报告它包含的缺点。JSLint 提出了比一般的 JavaScript 开发更严格的要求。它能让你确信你的程序只包含精华部分。
JavaScript 是一门反差鲜明的语言。它包含很多错误,而且多刺,所以你可能会疑惑:“为什么我要使用 JavaScript?”有两个答案。第一个是你没有选择。Web 已变成一个重要的应用开发平台,而 JavaScript 是唯一一门所有浏览器都可以识别的语言。很不幸,Java 在浏览器环境中失败了,否则想用强类型语言的人就有其他选择。但是 Java 确实失败了,而JavaScript 仍在蓬勃发展,这恰恰说明 JavaScript 确有其过人之处。
另一个答案是,尽管JavaScript 有缺陷,但是它真的很优秀。它既轻量级又富有表现力。并且一旦你熟练掌握了它,就会发现函数式编程是一件很有趣的事。
但是为了更好地使用这门语言,你必须知道它的局限。我将会无情地揭示它们,不要因此而气馁。这门语言的精华足以弥补它的糟粕。
一个简单的试验场
如果你有一个 Web 浏览器和任意一个文本编辑器,那么你就有了运行 JavaScript 程序所需要的一切。首先,请创建一个 HTML 文件,起个名字,比如 program.html:
<html><body><pre><scriptsrc=\'#\'" /p>
</script></pre></body></html>
接下来,在同一个文件夹内,创建一个脚本文件,比如起名为 program.js:
document.writeln('Hello, world!');
下一步,用你的浏览器打开你的 HTML 文件查看结果。本书贯彻始终都会用到一个 method方法去定义新方法。下面是它的定义:
Function.prototype.method = function (name, func) {
this.prototype[name] = func;
return this;
};
本文节选自《JavaScript语言精粹(修订版)》一书
(美)克罗克福德(Crockford,D.)著
赵泽欣,鄢学�d译
电子工业出版社出版