JavaScript语言精髓与编程实践(第3版)
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.3 没有框架与库的语言能怎样发展呢

1.3.1 做一个框架

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

于是,整个2003年,我基本上都没有再碰过浏览器上的开发。2004年年初的时候,我到一家新的公司任职。郑州佳讯,是一家主要为政府机构和电信运营商等提供解决方案与技术产品的软件公司。这家公司的主要业务都是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语言没有真正的“面向对象编程(OOP)”的框架。

在我所收集的资料中,第一个提出OOP JavaScript概念的是Brandon Myers,他在一个名为DynapiDynapi是早期最负盛名的一个JavaScript开源项目,它创建得比Bindows项目更早,参与者也更多。的开源项目工作中,提出了名为SuperClass的概念和原始代码。后来,在2001年3月,Bart Bizon按照这个思路发起了开源项目SuperClass,放在SourceForge上。这份代码维护到v1.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方面的补充。而接下来,另外两名开发人员他们分别是周鹏飞(leon)与周劲羽(yygw)。我们三人都姓周,实在是巧合。鹏飞后来成为微软的高级顾问和资深项目经理,现任万达集团信息管理中心副总经理。而劲羽则领导了Delphi界非常有名的开源项目CnPack&CnWizard的开发。则分别负责Application Framework与Database Layer的开发,他们的工作完成于2004年8月。紧接着,WEUI就被应用到一个商业项目的前期开发中了—WEUI很快显示出它在浏览器端的开发优势:它拥有完整的OOP框架与“基本够用”的组件库,为构建大型的浏览器端应用系统的可行性提供了实证。

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

1.3.2 重写框架的语言层

Qomo项目于2005年年末启动Qomo项目的早期设计目标是提供True OOP框架和面向浏览器的UI库,其详细资料见Git仓库(aimingoo/qomo)。,它一开始便立意于继承和发展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项目组发展到十余人,部分人员已经开始参与代码的编写和审查工作了。我得到了Zhe的有力支持Zhe的全名是方哲,喜欢研究跨平台兼容问题。他当时正提出并实现基于QNX6系统模块化网络架构的CAN栈。,他几乎独立完成了兼容层框架以及其在Mozilla、Safari等引擎上的兼容代码。很多开源界的,或者对JavaScript方面有丰富经验的朋友对Qomo提出了他们的建议,包括我后来的同事hax贺师俊(hax),是国内最早钻研ECMAScript语言规范的程序员之一,也是JavaScript标准委员会历史上首位来自中国公司的提案Champion。我和他因为在网上讨论JavaScript的OOP而结识。2006年,我在盛大担任架构师时曾将他招入盛大软件平台研发部。hax一直活跃于Web前端和JavaScript社区,自2018年年底开始,hax致力于推动中国互联网和科技公司加入ECMA TC39(即JavaScript语言标准委员会)。受此影响,360公司于2019年6月,阿里巴巴、华为、Sujitech于2019年12月,腾讯于2020年6月先后加入TC39。等。这些过程贯穿于整个Qomo的开发过程。

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

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

1.3.3 富浏览器端开发(RWC)与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出现之前就已经应用得很广泛了:在Internet Explorer等浏览器上采用“内嵌帧(IFrame)”载入并执行代码;在Netscape等不支持IFrame技术的浏览器中采用“层(Layer)”来载入并执行代码。这其中还有JSRS(JavaScript Remote Scripting),它的第一个版本发布于2000年8月。

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

■ IFRAME/LAYER标签在浏览器中没有得到广泛支持,也不被W3C标准所认可。

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

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

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

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

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

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

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

微软当然不会错过这样的机会。微软开始意识到,Flash已经成为“基于浏览器的操作平台”这一发展方向上不可忽视的障碍,因此一方面发展Altas项目,用.NET Framework+ASP.NET+VS.NET这个解决方案解决RWC开发中的现实问题,一方面启动被称为“Flash杀手”的Silverlight项目对抗Adobe在企业级、门户级富客户端开发中推广RIA思想。

此时,基于虚拟机而不是直接编译到native的方式已经成了执行环境的主流,因此编程语言体系也开始发生根本性的动摇。Adobe购得Macromedia之后,把基于JavaScript规范的ActionScript回馈给开源界,与Mozilla开始联手打造JavaScript 2;SUN在Java 6的JSR-223中直接嵌入来自Mozilla的Rhino JavaScript引擎,随后Java自己也开源了。在另一边,微软借助.NET虚拟执行环境在动态执行上天生的优势,全力推动DLR(Dynamic Language Runtime),其中包括Ruby、Python、JavaScript、VB等多种具有动态的、函数式特性的语言实现,这使得.NET Framework一路冲进了动态语言开发领域的角斗场。