JavaScript语言精髓与编程实践(第2版)(txt+pdf+epub+mobi电子书下载)


发布时间:2020-10-03 23:54:06

点击下载

作者:周爱民

出版社:电子工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

JavaScript语言精髓与编程实践(第2版)

JavaScript语言精髓与编程实践(第2版)试读:

内容简介

本书详细讲述JavaScript作为一种混合式语言的各方面特性,包括过程式、面向对象、函数式和动态语言特性等,在动态函数式语言特性方面有着尤为细致的讲述。本书的主要努力之一,就是分解出这些语言原子,并重现将它们混合在一起的过程与方法。通过从复杂性到单一语言特性的还原过程,读者可了解到语言的本质,以及“层出不穷的语言特性”背后的真相。

本书主要的著述目的是基于一种形式上简单的语言来讲述“语言的本质及其应用”。本书详细讲述了通过框架执行过程来构造一个JavaScript扩展框架的方法,并完整地讲述了框架扩展中各种设计取舍,因此可以作为研究计算机程序设计语言时的参考,用以展示现实系统如何实现经典理论中的各种编程范型。未经许可,不得以任何方式复制或抄袭本书之部分或全部内容。版权所有,侵权必究。图书在版编目(CIP)数据JavaScript语言精髓与编程实践/周爱民著. —2版. —北京:电子工业出版社,2012.3ISBN 978-7-121-15640-3Ⅰ. ①J… Ⅱ. ①周… Ⅲ. ①JAVA语言-程序设计 Ⅳ. ①TP312中国版本图书馆CIP数据核字(2011)第280709号策划编辑:张春雨责任编辑:刘 舫印  刷:北京丰源印刷厂装  订:三河市鹏成印业有限公司出版发行:电子工业出版社     北京市海淀区万寿路173信箱 邮编:100036开  本:787×980  1/16    印张:29.75  字数:666千字印  次:2012年3月第1次印刷印  数:4000册  定价:79.00元

凡所购买电子工业出版社图书有缺损问题,请向购买书店调换。若书店售缺,请与本社发行部联系,联系及邮购电话:(010)88254888。

质量投诉请发邮件至zlts@phei.com.cn,盗版侵权举报请发邮件至dbqq@phei.com.cn。

服务热线:(010)88258888。第2版 代序要有光—《世界需要一种什么样的语言》节选—

什么才是决定语言的未来的思想呢?或者我们也可以换个角度来提出这个问题:世界需要一种什么样的语言?

特性众多、适应性强,就是将来语言的特点吗?我们知道现在的C#与Java都在这条道路上前进。与特定的系统相关,就是语言的出路吗?例如曾经的VC++,以及它面向不同平台的版本。当然,与此类似的语言,还有C,以及汇编语言等。

这些例举其实都是在特定环境下的特定语言,所不同的无非是此处的环境的大小。这其实也是程序员的心病:我们到底选Windows平台,还是Java平台,或者Linux系统,再或者是……我们总是在不同的厂商及其支持的平台中选择,而最终这种选择又决定了我们所使用的语言。这与喜好无关,也与语言的好坏无关,不过是一种趋利的选择罢了。所以你在使用着的也许只是一种“并不那么‘好’”,以及并不能令你那么开心地编程的语言。你越发辛勤地工作,越发地为这些语言摇旗鼓噪,你也就离语言的真相越来越远。

当然,这不过是一种假设。但是,真相不都是从假设开始的吗?

语言有些很纯粹,有些则以混杂著称。如果编程世界只有一种语言,无论它何等复杂,也必因毫无比较而显得足够纯粹。所以只有在多种语言之间比较,才会有纯粹或混杂的差异:纯粹与混杂总是以一种或多种分类法为背景来描述的。

因此我们了解这些类属概念的标准、原则,也就回溯到了种种语言的本质:它是什么、怎么样,以及如何工作。这本书,将这些分类回溯到两种极端的对立:命令式与说明式、动态与静态。我讲述除静态语言(一般是指类似C、C++、Delphi等的强类型、静态、编译型语言)之外的其他三种类型。正是从根底里具有这三种类型的特性,所以JavaScript具有令人相当困扰的混合语言特性。分离它们,并揭示将它们混沌一物的方法与过程,如历经涅磐。在这一经历中,这本书就是我的所得。

多年以来,我在我所看不见的黑暗与看得见的梦境中追寻着答案。这本书是我最终的结论,或者结论面前的最后一层表象:我们需要从纯化的语言中领悟到编程的本质,并以混杂的语言来创造我们的世界。我看到:局部的、纯化的语言可能带来独特的性质,而从全局来看,世界是因为混杂而变得有声有色。如果上帝不说“要有光”,那么我们将不能了解世象之表;而世象有了表面,便有了混杂的色彩,我们便看不见光之外的一切事物。我们依赖于光明,而事实是光明遮住了黑暗。

如同你现在正在使用的那一种、两种或更多种语言,阻碍了你看到你的未来。周爱民2009年1月于本书精简版序第1版 代序学两种语言—《我的程序语言实践》节选—《程序设计语言——实践之路》一书对“语言”有一个分类法,将语言分类为“说明式”与“命令式”两种。Delphi以及C、C++、Java、C#等都被分在“命令式”语言范型的范畴,“函数式”语言则是“说明式”范型中的一种。如今我回顾自己对语言的学习,其实十年也就学会了两种语言:一种是命令式的Pascal/Delphi,另一种则是说明式的JavaScript。当然,从语言的实现方式来看,一种是静态的,一种是动态的。

这便是我程序员生涯的全部了。

我毕竟不是计算机科学的研究者,而只是其应用的实践者,因此我从一开始就缺乏对“程序”的某些科学的或学术层面上的认识是很正常的。也许有些人一开始就认识到程序便是如此,或者一种语言就应当是这样构成和实现的,那么他可能是从计算机科学走向应用,故而比我了解得多些。而我,大概在十年前学习编程以及在后来很多年的实践中,仅被要求“写出代码”而从未被要求了解“什么是语言”。所以我才会后知后觉,才会在很长的时间里迷失于那些精细的、沟壑纵横的语言表面而不自知。然而一如我现在所见到的,与我曾相同地行进于那些沟壑的朋友,仍然在持续地迷惑着、盲目着,全然无觉于沟壑之外的瑰丽与宏伟。

前些天写过一篇博客,是推荐那篇“十年学会编程”的。那篇文章道出了我在十年编程实践之后,对程序语言的最深刻的感悟。我们学习语言其实不必太多,深入一两种就可以了。如果在一种类型的语言上翻来覆去,例如不断地学C、Delphi、Java、C#……无非是求生存、讨生活,或者用以装点个人简历,于编程能力的提高用处是不大的。更多的人,因为面临太多的语言选择而浅尝辄止,多年之后仍远离程序根本,成为书写代码的机器,把书写代码的行数、程序个数或编程年限作为简历中最显要的成果。这在明眼人看来,不过是熟练的砌砖工而已。

我在《大道至简》中说“如今我已经不再专注于语言”。其实在说完这句话之后,我就已经开始了对JavaScript的深入研究。在如此深入地研究一种语言,进而与另一种全然有别的语言比较之后,我对“程序=算法+结构”有了更深刻的理解与认识。尽管这句名言从来未因我的认识而变化过,从来未因说明与命令的编程方式而变化过,也从来未因动态与静态的实现方法而变化过。

动静之间,不变的是本质。我之所以写这篇文章,并非想说明这种本质是什么抑或如何得到,只是期望读者能在匆忙的行走中,时而停下脚步,远远地观望一下目标罢了。

而我此刻,正在做一个驻足观望的路人。周爱民2007年11月于个人博客前 言语言

语言是一种交流的工具,这约定了语言的“工具”本质,以及“交流”的功用。“工具”的选择只在于“功用”是否能达到,而不在于工具是什么。

在数千年之前,远古祭司手中的神杖就是他们与神交流的工具。祭司让世人相信他们敬畏的是神,而世人只需要相信那柄神杖。于是,假如祭司不小心丢掉了神杖,就可以堂而皇之地再做一根。甚至,他们可以随时将旧的换成更新或更旧的神杖,只要他们宣称这是一根更有利于通神的杖。对此,世人往往做出迷惑的表情,或者呈现欢欣鼓舞的情状。今天,这种表情或情状一样地出现在大多数程序员的脸上,出现在他们听闻到新计算机语言被创生的时刻。

神杖换了,祭司还是祭司,世人还是会把头叩得山响。祭司掌握了与神交流的方法(如果真如同他们自己说的那样),而世人只看见了神杖。

所以,泛义的工具是文明的基础,而确指的工具却是愚人的器物。

计算机语言有很多种分类方法,例如高级语言或者低级语言。其中一种分类方法,就是将计算机语言分为“静态语言”和“动态语言”——事物就是如此,如果用一对绝对反义的词来分类,就相当于涵盖了事物的全体。当然,按照中国人中庸平和的观点,以及保守人士对未知可能性的假设,我们还可以设定一种中间态:半动态语言。你当然也可以叫它半静态语言。

所以,我们现在是在讨论一种很泛义的计算机语言工具。至少在眼下,它(在分类概念中)涵盖了计算机语言的二分之一。当然,限于我自身的能力,我只能讨论一种确指的工具,例如JavaScript。但我希望你由此看到的是计算机编程方法的基础,而不是某种愚人的器物。JavaScript的生命力可能足够顽强,我假定它比C语言还顽强,甚至比你我的生命都顽强。但它只是愚人的器物,因此反过来说:它能不能长久地存在并不重要,重要的是它能不能作为这“二分之一的泛义”来供我们讨论。分类法

打开一副新扑克牌,我们总看到它被整齐地排在那里,从A到K及大小王。接下来,我们将它一分为二,然后交叉在一起;再分开,再交叉……但是在重新开局之前,你是否注意到:在上述过程中,牌局的复杂性其实不是由“分开”这个动作导致的,而是由“交叉”这个动作导致的。

所以分类法本身并不会导致复杂性。就如同一副新牌只有4套A~K,我们可以按13种牌面来分类,也可以按4种花色来分类。当你从牌盒里把它们拿出来的时候,无论它们是以哪种方式分类的,这副牌都不混乱。混乱的起因,在于你交叉了这些分类。

同样的道理,如果世界上只有动态、静态两种语言,或者真有半动态语言而你又有明确的“分类法”,那么开发人员将会迎来清醒、明朗的每一天:我们再也不需要花更多的时间去学习更多的古怪语言了。

然而,第一个问题便来自于分类本身。因为“非此即彼”的分类必然导致特性的缺失——如果没有这样“非此即彼”的标准就不可能形成分类,但特性的缺失又正是开发人员所不能容忍的。

我们一方面吃着碗里的,一方面念着锅里的。即使锅里漂起来的那片菜叶未见得有碗里的肉好吃,我们也一定要捞起来尝尝。而且大多数时候,由于我们吃肉吃腻了嘴,因此会觉得那片菜叶味道更好。所以,是我们的个性决定了我们做不成绝对的素食者或肉食者。

当然,更有一些人说我们的确需要一个新的东西来使我们更加强[1]健。但不幸的是,大多数提出这种需求的人,都在寻求纯质银弹或[2]混合毒剂。无论如何,他们要么相信总有一种事物是完美武器,要么相信更多的特性放在一起就变成了魔力的来源。

我不偏向两种方法之任一。但是我显然看到了这样的结果,前者是我们在不断地创造并特化某种特性,后者是我们在不断地混合种种特性。

更进一步地说,前者在产生新的分类法以试图让武器变得完美,后者则通过混淆不同的分类法,以期望通过突变而产生奇迹。二者相同之处,在于都需要更多的分类法。

函数式语言就是来源于另外的一种分类法。不过要说明的是,这种分类法是计算机语言的原理之一。基本上来说,这种分类法在电子计算机的实体出现以前就已经诞生了。这种分类法的基础是“运算产生结果,还是运算影响结果”。前一种思想产生了函数式语言(如LISP)所在的“说明式语言”这一分类,后者则产生了我们现在常见的C、C++等语言所在的“命令式语言”这一分类。

然而我们已经说过,人们需要更多的分类的目的,是要么找到类似银弹的完美武器,要么找到混合毒剂。所以一方面很多人宣称“函数式是语言的未来”,另一方面也有很多人把这种分类法与其他分类法混在一起,于是变成了我们这本书所要讲述的“动态函数式语言”。毋庸置疑的是:还会有更多的混合法产生。因为保罗· 格雷厄姆[3](Paul Graham)已经做过这样的总结:“二十年来,开发新编程语言的一个流行的秘诀是:取C语言的计算模式,逐渐地往上加LISP模式的特性,例如运行时类型和无用单元收集。”

然而,这毕竟只是“创生一种新语言”的魔法。那么,到底有没有让我们在这浩如烟海的语言家族中,找到学习方法的魔法呢?

我的答案是:看清语言的本质,而不是试图学会一门语言。当然,这看起来非常概念化。甚至有人说我可能是从某本教材中抄来的,另外一些人又说我试图在这本书里宣讲类似于我那本《大道至简》里的[4]老庄学说。

其实这很冤枉。我想表达的意思不过是:如果你想把一副牌理顺,最好的法子,是回到它的分类法上,要么从A到K整理,要么按4个花[5]色整理。毕竟,两种或更多种分类法作用于同一事物,只会使事物混淆而不是弄得更清楚。

因此,本书从语言特性出发,把动态与静态、函数式与非函数式的语言特性分列出来。先讲述每种特性,然后再讨论如何去使用(例如交叉)它们。特性

无论哪种语言(或其他工具)都有其独特的特性,以及借鉴自其他语言的特性。有些语言通体没有“独特特性”,只是另外一种语言的副本,这更多的时候是为了“满足一些人使用语言的习惯”。还有一些语言则基本上全是独特的特性,这可能导致语言本身不实用,但却是其他语言的思想库。

我们已经讨论过这一切的来源。

对于JavaScript来说,除了动态语言的基本特性之外,它还有着[6]与其创生时代背景密切相关的一些语言特性。直到昨天,JavaScript的创建者还在小心翼翼地增补着它的语言特性。JavaScript轻量的、简洁的、直指语言本质的特性集设计,使它成为解剖动态语言的有效工具。这个特性集包括:

一套参考过程式语言惯例的语法。

一套以原型继承为基础的对象系统。

一套支持自动转换的弱类型系统。

动态语言与函数式语言的基本特性。

需要强调的是,JavaScript 1.x非常苛刻地保证这些特性是相应语言领域中的最小特性集(或称之为“语言原子”),这些特性在JavaScript中相互混合,通过交错与补充而构成了丰富的、属于JavaScript自身的语言特性。

本书的主要目的之一,就是分解出这些语言原子,并探究重新将它们混合在一起的过程与方法。通过从复杂性到单一语言特性的还原过程,让读者了解到语言的本质,以及“层出不穷的语言特性”背后的真相。技巧

技巧是“技术的取巧之处”,所以根本上来说,技巧也是技术的一部分。很多人(也包括我)反对技巧的使用,是因为难以控制,并且容易破坏代码的可读性。

哪种情况下代码是需要“易于控制”和“可读性强”呢?通常,我们认为在较大型的工程下需要“更好地控制代码”;在更多人共同开发的项目代码上要求“更好的可读性”。然而,反过来说,在一些更小型的、不需要更多人参与的项目中,“适度地”使用技巧是否就可以接受呢?

这取决于“需要、能够”维护这个代码的人对技巧的理解。这包括:

技巧是一种语言特性,还是仅特定版本所支持或根本就是BUG?

技巧是不是唯一可行的选择,有没有不需要技巧的实现?

技巧是为了实现功能,还是为了表现技巧而出现在代码中的?

即使知晓问题的答案,我仍然希望每一个技巧的使用都有说明,甚至示例。如果维护代码的人不能理解该技巧,那么连代码本身都失去了价值,更何论技巧存在于这份代码中的意义呢?

所以,虽然本书中的例子的确要用到许多“技巧”,但我一方面希望读者能明白,这是语言内核或框架内核实现过程中必需的,另一方面也希望读者能从这些技巧中学习到它原本的技术和理论,以及活用的方法。

然而对于很多人来说,本书在讲述一个完全不同的语言类型。在这种类型的语言中,本书所讲述的一切,都只不过是“正常的方法”;在其他类型的一些语言中,这些方法看起来就成了技巧。例如,在JavaScript中要改变一个对象方法指向的代码非常容易,并且是语言本身赋予的能力;而在Delphi/C++中,却成了“破坏面向对象设计”的非正常手段。

所以你最好能换一个角度来看待本书中讲述的“方法”。无论它对你产生多大的冲击,你应该先想到的是这些方法的价值,而不是它对于“你所认为的传统”的挑战。事实上,这些方法,在另一些“同样传统”的语言类型中,已经存在了足够长的时间——如同“方法”之于“对象”一样,原本就是那样“(至少看起来)自然而然”地存在于它所在的语言体系之中。

语言特性的价值依赖于环境而得以彰显。横行的螃蟹看起来古怪,但据说那是为了适应一次地磁反转。螃蟹的成功在于适应了一次反转,失败(我们是说导致它这样难看)之处,也在于未能又一次反转回来。这本书

你当然可以置疑:为什么要有这样的一本书?是的,这的确是一个很好的问题。

首先,这本书并不讲Web浏览器(Web Browser,例如Internet Explorer)。这可能令人沮丧,但的确如此。尽管在很多人看来,JavaScript就是为浏览器而准备的一种轻量的语言,并认为它离开了DOM、HTML、CSS就没有意义。在同样的“看法”之下,国内外的书籍在谈及JavaScript时,大多会从“如何在Web页面上验证一个输入框值的有效性”讲起。

是的,最初我也是这样认为的。因为本书原来就是出自我在写《B端开发》一书的过程之中。《B端开发》是一本讲述“在浏览器(Browser)上如何用JavaScript开发”的书。然而,《B端开发》写到近百页就放下了,因为我觉得应该写一本专门讲JavaScript的书,这更重要。

所以,现在你将要看到的这本书就与浏览器无关。在本书中我会把JavaScript提升到与Java、C#或Delphi一样的高度,来讲述它的语言实现与扩展。作为实践,本书还在最后一部分内容中,借助名为[7]“QoBean”的元语言框架讨论了语言扩展的方法。但是,总的来说,本书不讲浏览器,不讲Web,也并不讲“通常概念下的”AJAX。

JavaScript是一门语言,有思想的、有内涵的、有灵魂的语言。如果你没意识到这一点,那么你可能永远都只能拿它来做那个“验证一个输入框值的有效性”的代码。本书讲述JavaScript的这些思想、核心、灵魂,以及如何去丰富它的血肉。最为核心的内容是在第2章至第6章,包括:

以命令式为主的一般化的JavaScript语言特性,以及其对象系统。

动态、函数式语言,以及其他语言特性在JavaScript中的表现与应用。

使用动态函数式特性来扩展JavaScript的特性与框架。

在撰述这些内容的整个过程中,我一直在试图给这本书找到一个适合的读者群体,但我发现很难。因为通常的定义是低级、中级与高级,然而不同的用户对自己的“等级”的定义标准并不一样。在这其中,有“十年学会编程”的谦谨者,也有“三天学会某某语言”的速成家。所以,我认为这样定位读者的方式是徒劳的。

如果你想知道自己是否适合读这本书,建议你先看一下目录,然后试读一些章节。你可以先选读一些在你的知识库中看来很新鲜的,以及一些你原本已经非常了解的内容。通过对比,你应该知道这本书会给你带来什么。

不过我需要强调一些东西。这本书不是一本让你“学会某某语言”的书,也不是一本让初学者“学会编程”的书。阅读本书,你至少应该有一点编程经验(例如半年至一年),而且要摈弃某些偏见(例如C语言天下无敌或JavaScript是新手玩具)。

最后,你至少要有一点耐心与时间。[1]参见《人月神话》,美国弗雷德里克•布鲁克斯(Frederick P. Brooks, Jr.)著。[2]参见《蓝精灵》,比利时皮埃尔•居里福特(Pierre Culliford,Peyo)著。[3]保罗•格雷厄姆是计算机程序语言Arc的设计者,著有多本关于程序语言,以及创业方面的书籍。[4]这是一本软件工程方面的书,但往往被人看成是医学书籍或有人希望从中求取养生之道。[5]不过这都将漏掉两张王牌。这正是问题之所在,因为如果寻求“绝对一分为二的方法”,那么应该分为“王牌”和“非王牌”。但这往往不被程序员或扑克牌玩家们采用,因为极端复杂性才是他们的毕生目标。[6]在JavaScript 2——这是把银弹涂上毒剂以试图用单发手枪击杀恐龙的构想发布之前的“昨天”。[7]本书的第1版在实践部分介绍的是Qomo,而QoBean是Qomo的一个子项目。Qomo是有助于你在浏览器上构建大型应用的一个框架——如果你试图做这样的工作(例如基于AJAX的工程),那么你可以从Qomo中得益良多。它可以成倍地提高你的开发工效,有利于你实现更多的、更有价值的应用特性。(广告结束)第1部分 语言基础“我们最初利用JavaScript的目的,是让客户端的应用不必从服务器重新加载页面即可回应用户的输入信息,并且提供一种功能强大的图形工具包给脚本编写者。”(然而,JavaScript的)部分技术被采纳为所有浏览器的标准,而其他技术则没有。导致的结果是“不成熟的标准化、碎片化以及开发商受挫”。——JavaScript之父,Mozilla首席技术官Brendan Eich引自:英国《金融时报》“Google搜索网速的答案”第1章 十年JavaScriptCHAPTER

几乎每本讲JavaScript的书都会用很多的篇幅讲JavaScript的源起与现状。本书也需要这样吗?

不。我虽然也这样想过,但我不打算让读者去读一些能够从Wiki中摘抄出来的文字,或者在很多书籍中都可以看到的、千篇一律的文字。所以,我来写写我与JavaScript的故事。在这个过程中,你会看到一个开发者在每个阶段对JavaScript的认识,同时可以知道这本书的由来。

当然,一个人的历史,在一门语言的历史面前显得是那样的不足以道。因此除非编好故事性内容,对本章的前3个小节,你也可以选择跳过去。1.1 网页中的代码1.1.1 新鲜的玩意儿

1996年末,公司老板P&J找我去给他的一个朋友帮忙,做一些网页。那时事实上还没有说要做成网站。在那个时代,中国的IT人中可能还有2/3的触网者在玩一种叫“电子公告板(Bulletin Board System,BBS)”的东西——这与现在的BBS很不一样,它是一种利用现有电话网组成的PC-BBS系统,使用基于Telnet的终端登入操作。而另外1/3的触网者可能已经开始了互联网之旅,知道了像主页(Home Page)、超链接(Hyper Link)这样的一些东西。

我最开始做的网页只用于展示信息,是一个个单纯的、静态的网页,并通过一些超链接连接起来。当时网页开发的环境并不好(像现在的Dreamweaver这类程序,那时只能是梦想),因此我只能用记事本(notepad.exe)来写HTML。当时显示这些.htm文件的浏览器就是Netscape Navigator 3。

我很快就遇到了麻烦,因为P&J的朋友说希望让浏览网页的用户们能做更多的事,例如搜索等操作。我笑着说:“如果在电子公告板上,写段脚本就可以了;但在互联网上面,却要做很多的工作。”

事实上我并不知道要做多少的工作。我随后查阅的资料表明:不但要在网页中放一些表单让浏览者提交信息,还要在网站的服务器上写些代码来响应这些提交信息。我向那位先生摊开双手,说:“如果你真的想要这样做,那么我们可能需要三个月,或者更久。因为我还必须学习一些新鲜的玩意儿才行。”

那时的触网者,对这些“新鲜的玩意儿”的了解还几乎是零。因此,这个想法很自然地被搁置了。而我后来(1997年)被调到成都,终于有更多的机会接触Internet,而且浏览器环境已经换成了Internet Explorer 4.0。

那是一个美好的时代。通过互联网络,大量的新东西很快被传递进来。我终于有机会了解一些新的技术名词,例如CSS和JavaScript。当时(1997年12月)HTML 4.0的标准已经确定,浏览器的兼容性开始变得更好,Internet Explorer(以下简称IE)也越来越有取代Netscape Navigator(以下简称NN)而一统天下的趋势。除了这些,我还对在Delphi中进行ISAPI-CGI和ISAPI Filter开发的技术也展开了深入的学习。1.1.2 第一段在网页中的代码

1998年,我被调回到河南郑州,成为一名专职程序员,任职于当时一家开发反病毒软件的公司,主要工作是用Delphi做Windows环境下的开发。而当时我的个人兴趣之一,就是“做一个个人网站”。[1]那时大家都对“做主页”很感兴趣,我的老朋友傅贵就专门写了一套代码,以方便普通互联网用户将自己的主页放到“个人空间”里。同时,他还为这些个人用户提供了公共的BBS程序和一些其他的服务器端代码。但我并不满足于这些,我满脑子想的是做一个“自己的网站”。我争取到了一台使用IIS 4.0的服务器,由于有ISAPI-CGI这样的服务器端技术,因此一年多前的那个“如何让浏览者提交信息”的问题已经迎刃而解。而当时更先进的浏览器端开发技术也已经出现,例如Java Applet。我当时便选择了一个Java Applet来做“网页菜单”。

在当时,在IE中显示Java Applet之前需要装载整个JVM(Java Virtual Machine,Java虚拟机)。这对于现在的CPU来说,已经不是什么大不了的负担了,但当时这个过程却非常漫长。在这个“漫长的过程”中,网页显示一片空白,因此浏览者可能在看到一个“漂亮的菜单”之前就跑掉了。

为此我不得不像做Windows桌面应用程序一样,弄一个“闪屏窗口”放在前面。这个窗口只用于显示“Loading...”这样的文字(或图片)。而同时,我在网页中加入一个标签,使得JVM能偷偷地载入到浏览器中。然而,接下来的问题是:这个过程怎么结束呢?

我当时能找到的所有Java Applet都没有“在JVM载入后自动链接到其他网页”的能力。但其中有一个能力可以支持一种状态查询,它能在一个名为isInited的属性中返回状态True或False。

这时,我需要在浏览器中查询到这种状态,如果是True,就可以结束“Loading”过程,进入到真正的主页中去。由于JVM已经偷偷地载入过了,因此“漂亮的菜单”就能很快地显示出来。由于我得不到Java Applet的Java源代码并重写这个Applet去切换网址,因此这个“访问Java Applet的属性”的功能就需要用一种在浏览器中的技术来实现了。

这时跳到我面前的东西,就是JavaScript。我为此而写出的代码如下:1.1.3 最初的价值

JavaScript最初被开发人员接受,其实是一种无可奈何的选择。

首先,网景公司(Netscape Communications Corporation)很早就意识到:网络需要一种集成的、统一的、客户端到服务端的解决方[2]案。为此Netscape提出了LiveWire的概念,并设计了当时名为LiveScript的语言用来在服务器上创建类似于CGI的应用程序;与此同时,网景公司也意识到他们的浏览器NN中需要一个脚本语言的支持,解决类似于“在向服务器提交数据之前进行验证”的问题。1995年4月,网景公司招募了Brendan Eich,希望Brendan Eich来实现这样的一种语言,实现“使网页活动起来(Making Web Pages Come Alive)”。到了1995年9月,在发布NN 2.0 Beta时,LiveScript最早作为一种“浏览器上的脚本语言”被推到网页制作人员的面前;随后,在9月18日,网景公司宣布在其服务器端产品“LiveWire Server Extension Engine”中将包含一个该语言的服务器端(Server-[3]side)版本。

在这时,Sun公司的Java语言大行其道。Netscape决定在服务器端与Sun进行合作,这种合作后来扩展到浏览器,推出了名为Java Applet的“小应用”。而Netscape也借势将LiveScript改名,于1995年12月4日,在与Sun公司共同发布声明中首次使用了“JavaScript”这个名字,称之为一种“面向企业网络和互联网的、开放的、跨平台的[4]对象脚本语言”。从这种定位来看,最初的JavaScript在一定程度上是为了解决浏览器与服务器之间统一开发而实现的一种语言。

微软在浏览器方面是一个后来者。因此,它不得不在自己的浏览器中加入JavaScript的支持。但为了避免冲突,微软使用了“JScript”这个名字。微软在1996年8月发布IE 3时,提供了相当于NN 3的JavaScript脚本语言支持,但同时也提供了自己的VBScript。

当IE与NN进行那场著名的“浏览器大战”的时候,没有人能够看到结局。因此要想做一个“可以看的网页”,只能选择一个在两种浏览器上都能运行的脚本语言。这就使得JavaScript成为唯一可能正确的答案。当时,几乎所有的书籍都向读者宣导“兼容浏览器是一件天大的事”。为了这种兼容,一些书籍甚至要求网页制作人员最好不要用JavaScript,“让所有的事,在服务器上使用Perl或CGI去做好了”。

然而,随着IE 4.0的推出以及缘于DHTML(Dynamic HML,动态网页)带来的诱惑,一切都发生了改变。1.2 用JavaScript来写浏览器上的应用1.2.1 我要做一个聊天室

大概是在1998年12月中旬,我的个人网站完工了。这是一个文学网站,这个网站在浏览器上用到了Java Applet和JavaScript,并且为IE 4.0的浏览器提供了一个称为“搜索助手”的浮动条(FloatBar),用于快速地向服务器提交查询文章的请求。而服务器上则使用了用Delphi开发的ISAPI-CGI,运行于当时流行的Windows NT上的IIS系统。

我接下来冒出的想法是:要做一个聊天室。因为在我的个人网站中,论坛、BBS等都有其他网站免费提供,唯独没有聊天室。

1999年春节期间,我在四川的家中开始做这个聊天室并完成了原型系统(我称之为beta 0);一个月后,这个聊天室的beta 1终于在互联网上架站运行(如图1-1所示)。图1-1 聊天室的beta 1的界面

这个聊天室的功能集设定见表1-1。表1-1 聊天室beta 1的功能集设定

在这个聊天室的右上角有一个“隐藏帧”,是用Frameset来实现的。这是最早期实现Web RPC(Remote Procedure Call)的方法,那时网页开发还不推荐使用IFrame,也没有后来风行的AJAX。因此从浏览器下方的状态栏中,我们也可以看到这个聊天室在调用服务器上的.dll——这就是那个用Delphi写的ISAPI-CGI。当时我还不知道PHP,而且ASP也并不那么流行。

这个聊天室在浏览器上大量地使用了JavaScript。一方面,它用于显示聊天信息、控制CSS显示和实现界面上的用户交互;另一方面,我用它实现了一个Command Center,将浏览器中的行为编码成命令发给服务器的ISAPI-CGI。这些命令被服务器转发给聊天室中的其他用户,目标用户浏览器中的JavaScript代码能够解释这些命令并执行类似于“更名”、“更新列表”之类的功能——服务器上的ISAPI基本上只用于中转命令,因此效率非常高。你可能已经注意到,这其实与现在的AJAX的思想如出一辙。

虽然这个聊天室在beta 0时还尝试支持了NN 4,但在beta 1时就放弃了,因为IE 4提供的DHTML模型已经可以使用insertAdjacentHTML动态更新网页了,而NN 4仍只能调用document.write来修改页面。1.2.2 Flash的一席之地

我所在的公司也发现了互联网上的机会,成立了互联网事业部。我则趁机提出了一个庞大的计划,名为JSVPS(JavaScripts Visual Programming System)。

JSVPS在服务器端表现为dataCenter与dataBaseCenter。前者用于类似于聊天室的即时数据交互,后者则用于类似于论坛中的非即时数据交互。在浏览器端,JSVPS提出了开发网页编辑器和JavaScript组件库的设想。

这时微软的IE 4.x已经从浏览器市场拿到了超过70%的市场份额,开始试图把Java Applet从它的浏览器中赶走。这一策略所凭借的,便是微软在IE中加入的ActiveX技术。于是Macromedia Flash就作为一个ActiveX插件挤了进来。Flash在图形矢量表达能力和开发环境方面表现优异,使当时的Java Applet优势全失。一方面微软急于从桌面环境挤走Java,以应对接下来在.NET与Java之间的语言大战;另一方面Flash与Dreamweaver当时只是网页制作工具,因此微软并没有放在眼里,就假手Flash赶走了Java Applet。

Dreamweaver系列的崛起,使得网页制作工具的市场变得几乎没有了悬念。主力放在Java Applet的工具,如HotDog等都纷纷下马;而纯代码编辑的工具,如国产的CutePage则被Dreamweaver慢慢地蚕食着市场。同样的原因,JSVPS项目在浏览器端“开发网页编辑器”的设想最终未能实施,而“JavaScript组件库”也因为市场不明朗而一直不能投入开发。

服务器端的dataCenter与dataBaseCenter都成功地投入了商用。此后,我在聊天室上花了更多的精力。到2001年下半年,它已经开始使用页签形式来管理多房间同时聊天,并加入语言过滤、表情、行为和用户界面定制等功能。而且,通过对核心代码的分离,聊天室已经衍生出“Web即时通信工具”和“网络会议室”这样的版本。

2002年初,聊天室发布的最终版本(ver 2.8)的功能设定已经远远超出了现在网上所见的Web聊天室的功能集。图1-2中,聊天室最终版本的界面包括颜色选取器、本地历史记录、多房间管理、分屏过滤器、音乐、动作、表情库和Outlook样式的工具栏,以及中间层叠的窗体,都是由DHTML与CSS来动态实现的。在后台驱动这一切的,就是JavaScript。图1-2 聊天室最终版本的界面

我没有选择这时已经开始流行的Flash,因为用DHTML做聊天室的界面效果并不逊于Flash,也因为在RWC与RIA的战争中,我选择了前者。1.2.3 RWC与RIA之争

追溯RWC的历史,就需要从“动态网页”说起。在1997年10月发布的IE 4中,微软提供了JScript 3,这包括当时刚刚发布的ECMAScript Editon 1,以及尚未发布的JavaScript 1.3的很多特性。最重要的是,微软颇有创见地将CSS、HTML与JavaScript技术集成起来,提出了DHTML开发模型(Dynamic HTML Model),这使得几乎所有的网页都开始倾向于“动态(Dynamic)”起来。

开始,人们还很小心地使用着脚本语言,但当微软用IE 4在浏览器市场击败网景之后,很多人发现:没有必要为10%的人去多写90%的代码。因此,“兼容”和“标准”变得不再重要。于是DHTML成了网页开发的事实标准,以至于后来由W3C提出的DOM (Document Object Model)在很长一个阶段中都没有产生任何影响。

这时,成熟的网页制作模式,使得一部分人热衷于创建更有表现能力和实用价值的网页,他们把这样的浏览器和页面叫做“Rich Web Client”,简称RWC。Rich Web的概念产于何时已经不可考,但Erik Arvidsson一定是这其中的先行者。他拥有一个知名的个人网站WebFX(http://webfx.eae.net/)。从1997开始,他在WebFX上公布关于浏览器上开发体验的文章和代码。他可能是最早通过JavaScript+DHTML实现menu、tree及tooltip的人。1998年末,他就已经在个人网站上实现了一个著名的WebFX Dynamic WebBoard,如图1-3所示。这套界面完整地模仿了Outlook,因而是在Rich Web Client上实现类Windows界面的经典之作。图1-3 WebFX Dynamic WebBoard的仿Outlook界面

在这时盛行的Flash也需要一种脚本语言来表现动态的矢量图形。因此,Macromedia很自然地在Flash 2中开始加入一种名为Action的脚本支持。在Flash 3时,该脚本参考了JavaScript的实现,变得更为强大。随后Macromedia又干脆以JavaScript作为底本完成了自己的ActionScript,并加入到Flash 5中。随着ActionScript被浏览器端开发人员逐渐接受,这种语言也日渐成熟,于是Macromedia开始提出自己的对“浏览器端开发”的理解。这就是有名的RIA(Rich Internet Application)。

这样一来,RIA与RWC分争“富浏览器客户端应用(Rich Web-client Application,RWA)”市场的局面出现了——微软开始尝到自己种下的苦果:一方面它通过基于ActiveX技术的Flash赶走了Java Applet,另一方面却又使得Dreamweaver和Flash日渐坐大,实在是“前门拒虎,后门进狼”。微软用丢失网页编辑器和网页矢量图形事实标准的代价,换取了在开发工具(如Virtual Studio .NET)和语言标准(如CLS,即Common Language Specification)方面的成功。而这个代价的直接表现之一,就是RIA对RWC的挑战。

RIA的优势非常明显,在Dreamweaver UltraDev 4.0发布之后,Macromedia成为网页编辑、开发类工具市场的领先者。而在服务器端,有基于Server Page思路的ColdFusion、优秀的J2EE应用服务器JRun和面向RIA模式的Flash组件环境Flex。这些构成了完整的B/S三层开发环境。然而似乎没有人能容忍Macromedia独享浏览器开发市场,并试图染指服务器端的局面,所以RIA没有得到足够的商业支持。另外,ActionScript也离JavaScript越来越远,既不受传统网页开发者的青睐,而对以设计人员为主体的Flash开发者来讲又设定了过高的门槛。

RWC的状况则更加尴尬。因为JavaScript中尽管有非常丰富的、开放的网络资源,但却找不到一套兼容的、标准的开发库,也找不到一套规范的对象模型(DOM与DHTML纷争不断),甚至连一个统一的代码环境都不存在(没有严格规范的Host环境)。

在RIA热捧浏览器上的Rich Application市场的同时,自由的开发者们则在近乎疯狂地挖掘CSS、HTML和DOM中的宝藏,试图从中寻找到RWC的出路。支持这一切的,是JavaScript 1.3~1.5,以及在W3C规范下逐渐成熟的Web开发基础标准。在这整个过程中,RWC都只是一种没有实现的、与RIA的商业运作进行着持续抗争的理想而已。1.3 没有框架与库的语言能怎样发展呢1.3.1 做一个框架

聊天室接下来的发展几乎停滞了。我在RWC与RIA之争中选择了RWC,但也同时面临了RWC的困境:找不到一个统一的框架或底层环境。因此,聊天室如果再向下发展,也只能是在代码堆上堆砌代码而已。

因此,整个2003年,我基本上都没有再碰过浏览器上的开发。2004年初的时候,我到一家新的公司(Jxsoft Corporation)任职。这家公司的主要业务都是B/S架构上的开发,于是我提出“先做易做的1/2”的思路,打算通过提高浏览器端开发能力,来加强公司在B/S架构开发中的竞争力。

于是我得到很丰富的资源,来主持一个名为WEUI(Web Enterprise UI Component Framework)项目的开发工作。这个项目的最初设想,跟JSVPS一样是个庞然大物(似乎我总是喜欢如图1-4所示的这类庞大的构想)。图1-4 WEUI基本框架和技术概览

WEUI包括了B/S两端的设计,甚至还有自己的一个开发环境。而真正做起来的时候,则是从WEUI OOP Framework开始的。这是因为JavaScript语言没有真正的“面向对象编程(Object Oriented Programming,OOP)”框架。

在我所收集的资料中,第一个提出OOP JavaScript概念的是[5]Brandon Myers,他在一个名为Dynapi的开源项目工作中,提出了名为“SuperClass”的概念和原始代码。在2001 年3月,Bart Bizon按照这个思路发起了开源项目SuperClass,放在SourceForge上。这份代码维护到ver 1.7b。半年后,Bart Bizon放弃了SuperClass并重新发起JSClass项目,这成为JavaScript早期框架中的代表作品。

后来许多JavaScript OOP Framework都不约而同地采用了与SuperClass类同的方法——使用“语法解释器”来解决框架问题。然而前面提到过的实现了“类Outlook界面”的Erik Arvidsson则采用了另一种思路:使用JavaScript原生代码(native code)在执行期建立框架,并将这一方法用在了另一个同样著名的项目Bindows上。

对于中国的一部分的JavaScript爱好者来说,RWC时代就开始于《程序员》2004年第5期的一篇名为《王朝复辟还是浴火重生——The Return of Rich Client》的文章。这篇文章讲的就是Bindows在浏览器上的不凡表现,如图1-5所示。图1-5 Bindows在浏览器上的不凡表现

Bindows可能也是赶上了好时候,这年的MS Teched就有好几个专场来讲述智能客户端(Smart Client)。而智能客户端的基本思想就是跨平台的、弹性的富客户端(Rich Client)。因此“丰富的浏览器表现”立即成为“时新”的开发需求,以Bindows为代表的RWC也因此成为国内开发者和需求方共同关注的焦点。

WEUI v1.0内核的研发工作大概就结束于此时。我在这个阶段中主要负责的就是JavaScript OOP Language Core的开发,并基本完成了对JavaScript语言在OOP方面的补充。而接下来,另外的两名开发

[6]人员则分别负责Application Framework与Database Layer的开发,他们的工作完成于2004年8月。紧接着WEUI就被应用到一个商业项目的前期开发中了。WEUI很快显示出它在浏览器端的开发优势:它拥有完整的OOP框架与“基本够用”的组件库,为构建大型的浏览器端应用系统的可行性提供了实证。

WEUI在开发环境和服务器端上没有得到投入。这与JSVPS有着基本相同的原因:没有需求。于是从2004年底开始,我就着手于以用户界面(UI)组件库为主要目标的WEUI v2.0的开发,直到2005年3月。1.3.2 重写框架的语言层

Qomo项目于2005年末启动,它自一开始便立意于继承和发展WEUI框架。为此我联系了WEUI原项目组以及产品所有的公司,并获得了基于该项目开源的授权。

从WEUI到Qomo转变之初,我只是试图整理一套有关WEUI的文档,并对WEUI内核中有关OOP的部分做一些修补。因此在这个阶段,我用了一段时间撰写公开文档来讲述JavaScript的基本技术,这包括一组名为《JavaScript面向对象的支持》的文章。而这个过程正好需要我深入地分析JavaScript对象机制的原理,以及这种原理与Qomo项目中对OOP进行补充的技术手段之间的关系。然而这个分析的过程,让我汗如雨下:在此以前,我一直在用一种基于Delphi的面向对象思想的方式,来理解JavaScript中的对象系统的实现。这种方式完全忽略了JavaScript的“原型继承”系统的特性,不但弃这种特性优点于不顾,而且很多实现还与它背道而驰。换而言之,WEUI中对于OOP的实现,不但不是对JavaScript的补充,反而是一种伤害。

于是,我决定重写WEUI框架的语言层。不过在做出这个决定时,我仍然没有意识到WEUI的内部其实还存在着非常多的问题——这其中既有设计方面的,也有实现方面的问题。但我已经决定在WEUI向Qomo转化的过程中,围绕这些(已显现或正潜藏着的)问题开始努力了。

Qomo Field Test 1.0发布于2006年2月中旬,它其实只包括一个$import()函数的实现,用于装载其他模块。两个月之后终于发布了beta 1,已经包括了兼容层、命名空间,以及OOP、AOP、IOP三种程序设计框架基础。这时Qomo项目组发展到十余人,部分人员已经[7]开始参与代码的编写和审查工作了。我得到了Zhe的有力支持,他几乎独立完成了兼容层框架以及其在Mozilla、Safari等引擎上的兼容代码。很多开源界的,或者对JavaScript方面有丰富经验的朋友对[8]Qomo提出了他们的建议,包括我后来的同事hax等。这些过程贯穿于整个Qomo开发过程之中。

在经历过两个beta之后,Qomo赶在2007年2月前发布了v1.0 final。这个版本包括了Builder系统、性能分析与测试框架,以及公共类库。此外,该版本也对组件系统的基本框架做出了设计,并发布了Qomo的产品路线图,从而让Qomo成为一个正式可用的、具有持续发展潜力的框架系统。

回顾WEUI至Qomo的发展历程,后者不单单是前者的一个修改版本,而几乎是在相同概念模型上的、完全不同的技术实现。Qomo摒弃了对特殊的或具体语言环境相关特性的依赖,更加深刻地反映了JavaScript语言自身的能力。不但在结构上与风格上更为规范,而且在代码的实用性上也有了更大的突破。即使不讨论这些(看起来有些像宣传词的)因素,仅以我个人而言,正是在Qomo项目的发展过程中,加深了我对JavaScript的函数式、动态语言特性的理解,也渐而渐之地丰富了本书的内容。1.3.3 富浏览器端开发与AJAX

事情很快发生了变化——起码,看起来时代已经变了。因为从2005年开始,几乎整个B/S开发界都在热情地追捧一个名词:AJAX。

AJAX中的“J”就是指JavaScript,它明确地指出这是一种基于JavaScript语言实现的技术框架。但事实上它很简单,如果你发现它的真相不过是“使用一个对象的方法而已”,那么你可能会不屑一顾。因为如果在C++、Java或Delphi中,有人提出一个名词/概念(例如Biby),说“这是如何使用一个对象的技术”,那绝不可能得到如AJAX般的待遇。

然而,就是这种“教你如何用一个对象”的技术在2005年至2006年之间突然风行全球。Google基于AJAX构建了Gmail;微软基于AJAX提出了Atlas;Yahoo发布了YUI(Yahoo! User Interface);IBM则基于Eclipse中的WTP(Web Tools Project)发布了ATF(AJAX Toolkit Framework)……一夜之间,原本在技术上对立或者竞争的公司都不约而同地站到了一起:它们不得不面对这种新技术给互联网带来的巨大机会。

事实上在AJAX的早期就有人注意到这种技术的本质不过是同步执行。而同步执行其实在AJAX出现之前就已经应用得很广泛:在IE等浏览器上采用“内嵌帧(IFrame)”载入并执行代码;在Netscape等不支持IFrame技术的浏览器中采用“层(Layer)”来载入并执行代码。这其中就有JSRS(JavaScript Remote Scripting),它的第一个版本发布于2000年8月。

但是以类似于用JSRS的技术来实现的HTTP-RPC方案存在两个问题:

Iframe/Layer标签在浏览器中没有得到广泛的支持,也不为W3C标准所认可。

HTTP-RPC没有提出数据层的定义和传输层的确切实施方案,而是采用B/S两端应用自行约定协议。

然而这仍然只是表面现象。JSRS一类的技术方案存在先天的不足:它仅仅是技术方案,并不是应用框架,也没有任何商业化公司去推动这种技术。而AJAX一开始就是具有成熟商业应用模式的框架,而且许多公司快速地响应了这种技术并基于它创建了各自的“同步执行”的解决方案和编程模型。因此真正使AJAX浮上水面的并不是“一个XMLHttpRequest对象的使用方法”,也并不因为它是“一种同步和异步载入远程代码与数据的技术”,而是框架和商业标准所带来的推动力量。

这时人们似乎已经忘却了RWC。而W3C却回到了这个技术名词上,并在三个主要方面对RWC展开了标准化的工作:

复合文档格式(Compound Document Formats,CDF)。

Web标准应用程序接口(Web APIs)。

Web标准应用程序格式(Web Application Formats)。

这其中,CDF是对AJAX中的“X”(即XML)提出标准;而Web APIs则试图对“J”(即JavaScript)提出标准。所以事实上,无论业界如何渲染AJAX或者其他的技术模型或框架,Web上的技术发展方向仍然会落足到“算法+结构”这样的模式上来。这种模式在浏览器上的表现,后者是由XML/XHTML标准化来实现的,而前者就是由JavaScript语言来驱动的。

微软当然不会错过这样的机会。微软开始意识到Flash已经成为“基于浏览器的操作平台”这一发展方向上不可忽视的障碍,因此一

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载